HDU 4776 Ants tire+优先队列
来源:互联网 发布:mac内存清理软件 编辑:程序博客网 时间:2024/05/16 11:12
【题目大意】
有一棵树,树上一条简单路径(u,v)的价值定义为这条路径的所有边的异或和。求这些价值的第k大。
【思路】
如果我们统计根到节点u,路径的异或和为a[u],显然,路径(u,v)的价值为a[u]^a[v]。问题变为了从n个数中选两个不同的数,求异或,找第k大。因为k其实不是很大,我们可以考虑将1-max(k)的价值都找出来。用a[]建立tire树,首先枚举路径的左端点,通过tire找到一个右端点,使得其异或值最大。把这些数加入优先队列,显然,这些数中,最大的那个,就是第一大的价值。然后把这个价值删掉,通过原来的左端点,再找一个右端点,使其异或值变成次大,并把这个值加入优先队列。这个时候,队列中最大的元素是第二大的价值。这样一直找下去,就能把所有k都找到。
#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<cmath>#include<cctype>#include<string>#include<algorithm>#include<iostream>#include<ctime>#include<map>#include<set>using namespace std;#define MP(x,y) make_pair((x),(y))#define PB(x) push_back(x)typedef __int64 LL;//typedef unsigned __int64 ULL;/* ****************** */const LL INF = 1LL<<55;const double INFF = 1e100;const double eps = 1e-8;const LL mod = 10000000007LL;const int NN = 100010;const int MM = 5000010;/* ****************** */const int limit = 59;struct G{ int v, next; LL w;}E[NN*2];int p[NN], T;struct node{ LL x, x_xor; int num; node(LL a = 0,LL b = 0,int c = 0):x(a),x_xor(b),num(c){} bool operator<(const node &tt)const { return x_xor < tt.x_xor; }};LL a[NN];struct Tire{ int num; int ch[2]; void init() { num = 0; memset(ch, -1, sizeof(ch)); }}tire[NN*60];struct Q{ int k, id; bool operator<(const Q &tt)const { return k < tt.k; }}q[NN];LL anss[NN];void add(int u,int v,LL w){ E[T].v = v; E[T].w = w; E[T].next = p[u]; p[u] = T++;}void dfs(int u,int fa){ int i, v; for(i = p[u]; i + 1; i = E[i].next) { v = E[i].v; if(v == fa)continue; a[v] = a[u]^E[i].w; dfs(v, u); }}void tire_insert(LL val,int root,int &tire_cnt){ int i, x, p = root; for(i = limit; i >=0; i --) { if(val&(1LL<<i)) x = 1; else x = 0; if(tire[p].ch[x]==-1) { tire[p].ch[x] = ++tire_cnt; tire[tire_cnt].init(); } p = tire[p].ch[x]; } tire[p].num ++;}LL tire_find_max(LL val,int root,int &num){ int i, x, p = root; LL ans = 0; for(i = limit; i >= 0; i --) { if(val&(1LL<<i)) x = 0; else x = 1; if(tire[p].ch[x]!=-1) { ans |= (1LL<<i); p = tire[p].ch[x]; } else { p = tire[p].ch[x^1]; } } num = tire[p].num; return ans;}LL tire_find_lower(LL val,LL x_xor,int root,int &num){ int i, x, xx, p = root; int last = -1; LL ans = 0; for(i = limit; i >= 0; i --) { if( (val^x_xor)&(1LL<<i) ) x = 1; else x = 0; if( val&(1LL<<i)) xx = 0; else xx = 1; if(tire[p].ch[x^1]!=-1 && x == xx) last = i; p = tire[p].ch[x]; } if(last==-1)return -1; p = root; for(i = limit; i >= 0; i--) { if(i >= last) { if( (val^x_xor)&(1LL<<i) ) x = 1; else x = 0; if(i == last) x = (x^1); } else { if(val&(1LL<<i)) x = 0; else x = 1; if(tire[p].ch[x]==-1) x = (x^1); } if( ( val^((LL)x<<i) )&(1LL<<i) ) ans |= (1LL<<i); p = tire[p].ch[x]; } num = tire[p].num; return ans;}void solve(int n,int m){ int i, j, tire_root, tire_cnt, num; LL t; priority_queue<node>my_q; tire_root = tire_cnt = 0; tire[tire_root].init(); for(i = 1; i <= n; i ++) { tire_insert(a[i], tire_root, tire_cnt); } for(i = 1; i <= n; i ++) { t = tire_find_max(a[i], tire_root, num); my_q.push( node(a[i], t, num) ); } j = 1; memset(anss, -1, sizeof(anss)); for(i = 1; i <= (LL)n*(n-1) && j <= m ; i ++) { node ix = my_q.top(); my_q.pop(); while(j <= m && i==q[j].k) { anss[q[j].id] = ix.x_xor; j ++; } if(ix.num > 1) { my_q.push( node(ix.x, ix.x_xor, ix.num-1) ); } else { t = tire_find_lower(ix.x, ix.x_xor, tire_root, num); if(t!=-1) my_q.push( node(ix.x, t, num) ); } } for(i = 1; i <= m; i ++) printf("%I64d\n", anss[i]);}int main(){ int n, m, u, v, i; LL t; while(scanf("%d", &n) != EOF) { if(n==0)break; memset(p, -1, sizeof(p)); T = 0; for(i = 1; i < n; i ++) { scanf("%d%d", &u, &v); scanf("%I64d", &t); add(u, v, t); add(v, u, t); } a[1] = 0; dfs(1,-1); scanf("%d", &m); for(i = 1; i <= m; i ++) { scanf("%d", &q[i].k); q[i].id = i; } sort(q+1,q+1+m); solve(n, m); } return 0;}
0 0
- HDU 4776 Ants tire+优先队列
- HDU 4776 Ants(字典树+优先队列+思维题)
- hdu 4776 Ants
- HDU-1509 优先队列
- hdu 4006 优先队列
- hdu 2757 优先队列
- HDU 4006 优先队列
- hdu 1509 优先队列
- HDU 4006优先队列
- hdu 1873优先队列
- 【优先队列】HDU Rescue
- HDU 4546 优先队列
- hdu 5437 (优先队列)
- hdu-5596 优先队列
- hdu 4544 优先队列
- HDU 4302 优先队列
- HDU 5360 优先队列
- hdu 5810 优先队列
- iphone开发自定义UIControl对象的视图 UISwitch的字体和颜色
- 电梯
- LeetCode-Palindrome Number
- 单片机程序架构(一)时间片轮询
- struts的优缺点
- HDU 4776 Ants tire+优先队列
- POJ 1149 PIGS(最大流+建图)
- 母函数(指数型)系列之 排列组合 hdoj 1521
- 推荐:天下没有免费的午餐
- 浪潮之巅——读书笔记+摘录+感悟
- iOS 多线程 锁 互斥 同步
- ReportStudio入门教程(八十一) - 下钻后负责人信息异常
- 小改进大奖励,大建议只鼓励
- 使用jOrgChart插件, 异步加载生成组织架构图