HDU 5877 Weak Pair 大连网络赛
2016-09-12 21:02
417 查看
题意就是说给你一棵有根树,然后定义了一种有序对叫做weak pair,两个点若满足 第一个点是第二个点的祖先,而且第一个点和第二个点的权值相乘,乘积小于他给的k,那么就是weak pair,方法很简单,就是dfs,从根节点开始向下找,看这个点和他的祖先节点有多少满足情况,比赛时的想法是dfs到某个深度的时候,把之前的所有祖先的权值存在一个数组里,然后去看有多少符合条件的加在ans里,然后超时了,gg,怎么也没想到优化,后来知道有splay树这种东西,可以很快找到有多少符合条件的,但是不会呀,所以看了别人的做法,有用treap的,就用了treap的模板(之前也对这玩意不怎么熟,只知道有这个东西不会用),方法是,看祖先节点中有多少权值小于
k/当前节点权值 ,这样子就比较快了。
k/当前节点权值 ,这样子就比较快了。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; typedef long long LL; int n, m; int a[100005]; int in[100005]; int head[100005]; LL k; LL ans; int cnt; struct Edge { int from, to; int next; }edge[100005]; void addedge(int u, int v) { edge[cnt].next = head[u]; edge[cnt].from = u; edge[cnt].to = v; head[u] = cnt++; } struct Treap { int size; int fix; LL key; Treap *ch[2]; Treap(LL key) { size = 1; fix = rand(); this->key = key; ch[0] = ch[1] = NULL; } int cmp(LL x) const { if (x == key) return -1; return x < key ? 0 : 1; } void Maintain() { size = 1; if (ch[0] != NULL) size += ch[0]->size; if (ch[1] != NULL) size += ch[1]->size; } }; void Rotate(Treap* &t, int d) { Treap *k = t->ch[d ^ 1]; t->ch[d ^ 1] = k->ch[d]; k->ch[d] = t; t->Maintain(); k->Maintain(); t = k; } void Insert(Treap* &t, LL x) { if (t == NULL) t = new Treap(x); else { int d = (x < t->key ? 0 : 1); Insert(t->ch[d], x); if (t->ch[d]->fix > t->fix) Rotate(t, d ^ 1); } t->Maintain(); } void Delete(Treap* &t, LL x) { int d = t->cmp(x); if (d == -1) { Treap *tmp = t; if (t->ch[0] == NULL) { t = t->ch[1]; delete tmp; tmp = NULL; } else if (t->ch[1] == NULL) { t = t->ch[0]; delete tmp; tmp = NULL; } else { int k = (t->ch[0]->fix > t->ch[1]->fix ? 1 : 0); Rotate(t, k); Delete(t->ch[k], x); } } else Delete(t->ch[d], x); if (t != NULL) t->Maintain(); } bool Find(Treap *t, LL x) { while (t != NULL) { int d = t->cmp(x); if (d == -1) return true; t = t->ch[d]; } return false; } int Rank(Treap *t, LL x) { int r; if (t == NULL) return 0; if (t->ch[0] == NULL) r = 0; else r = t->ch[0]->size; if (x == t->key) return r + 1; if (x < t->key) return Rank(t->ch[0], x); return r + 1 + Rank(t->ch[1], x); } void DeleteTreap(Treap* &t) { if (t == NULL) return; if (t->ch[0] != NULL) DeleteTreap(t->ch[0]); if (t->ch[1] != NULL) DeleteTreap(t->ch[1]); delete t; t = NULL; } void search(int u, Treap* &t) { //if (head[u] == -1) return; LL Max = 0x3f3f3f3f3f3f3f3f; if (a[u]) Max = k / (a[u]); ans += Rank(t, Max); Insert(t, a[u]); for (int i = head[u]; i != -1; i = edge[i].next) search(edge[i].to, t); Delete(t, a[u]); return; } int main(void) { //freopen("test.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { ans = 0; cnt = 0; memset(in, 0, sizeof in); memset(head, -1, sizeof head); Treap *root = NULL; scanf("%d%lld", &n, &k); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int l, r; for (int i = 0; i < n - 1; i++) { scanf("%d%d", &l, &r); addedge(l, r); in[r]++; } for (int i = 1; i <= n; i++) { if (in[i] == 0) { search(i, root); break; } } DeleteTreap(root); printf("%lld\n", ans); } return 0; }
相关文章推荐
- 数据结构之Treap详解
- Win2003利用dfs(分布式文件系统)在负载均衡下的文件同步配置方案
- win2003分布式文件系统(dfs)配置方法[图文详解]
- win2003分布式文件系统及其部署 图文教程
- Hadoop2.6+jdk8的安装部署(1)——使用jar包安装部署【详细】
- Hadoop FS Shell
- DFS使用方法总结
- FastDFS注意事项
- 无忧技术带您预览DFS(分布式文件系统)管理控制台
- C 语言实现迷宫 DFS算法
- 深度优先搜索算法
- Treap(树堆)
- 一幅图弄清DFT与DTFT,DFS的关系
- HDFS---Namenode
- HDFS ---- Services startup
- POJ1523 SPF dfs
- 329. Longest Increasing Path in a Matrix
- poj1731 Orders dfs
- 【日常练习】Prime Ring Problem(素数环)
- Surrounded Regions