[HDU 4776 Ants] Trie异或+预处理
来源:互联网 发布:智慧树网络课程好过吗? 编辑:程序博客网 时间:2024/06/18 18:19
题目
http://acm.hdu.edu.cn/showproblem.php?pid=4776
分析
Trie异或+预处理
有点用到NOI 2011 Piano的思想的意思,因为k不大,所以把k大值一个一个都找出来
首先做一遍bfs把每个点到根的距离dist[]求出来,那么两个点的距离就是dist的异或值
然后把n个点的dist都插进trie里,然后把每个点的最大值都找出来,丢进一个堆里,然后每次取出最大的,把对应的点的下一个最大值插进堆里
找每个点的k大值可以通过在trie上记录size解决
练习赛时ans数组开小了wa了好几次
代码
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <vector>#include <queue>using namespace std;typedef long long ll;const int MAX_N = 100005;const int MAX_E = 200005;const int MAX_K = 200005;const int MAX_M = 6400005;struct Node { int size; Node *ch[2]; Node() { size = 0; memset(ch, 0, sizeof(ch)); }};struct Edge { int dest; ll cost; Edge *next; Edge() {} Edge(int _dest, ll _cost, Edge *_next) : dest(_dest), cost(_cost), next(_next) {}};Edge EdgePool[MAX_E];Edge *EP;Edge *e[MAX_N];priority_queue< pair<ll, int> > heap;Node NodePool[MAX_M];Node *NP;Node *root;int n;ll dist[MAX_N];ll ans[MAX_K];int cur[MAX_N];int Q[MAX_N];bool vis[MAX_N];inline void addedge(int a, int b, ll c) { e[a] = new(EP++)Edge(b, c, e[a]); e[b] = new(EP++)Edge(a, c, e[b]);}void insert(ll val) { Node *t = root; for (int i = 63; i >= 0; i--) { t->size++; int c = (int)((val >> i) & 1); if (!t->ch[c]) { t->ch[c] = new(NP++)Node(); } t = t->ch[c]; } t->size++;}ll query(ll val, int k) { Node *t = root; ll ret = 0; for (int i = 63; i >= 0; i--) { ret <<= 1; int c = (int)((val >> i) & 1); int _c = c ^ 1; if (t->ch[_c] && t->ch[_c]->size >= k) {// printf("0 (%d, %d) %d\n", _c, t->ch[_c]->size, k); t = t->ch[_c]; ret |= _c; } else {// printf("1 (%d, %d) %d\n", c, (t->ch[_c] ? t->ch[_c]->size : 0), k); k -= t->ch[_c] ? t->ch[_c]->size : 0; t = t->ch[c]; ret |= c; } }// printf("\n"); ret ^= val; return ret;}int main() {// freopen("in.txt", "r", stdin); while (scanf("%d", &n), n) { EP = EdgePool; memset(e, 0, sizeof(e)); NP = NodePool; root = new(NP++)Node(); memset(dist, 0, sizeof(dist)); memset(vis, 0, sizeof(vis)); while (!heap.empty()) { heap.pop(); } for (int i = 1; i < n; i++) { int a, b; ll c; scanf("%d %d %I64d", &a, &b, &c); addedge(a, b, c); } int tail = 0; Q[++tail] = 1; for (int head = 1; head <= tail; head++) { int i = Q[head]; vis[i] = true; for (Edge *j = e[i]; j; j = j->next) { if (!vis[j->dest]) { dist[j->dest] = dist[i] ^ j->cost; Q[++tail] = j->dest; } } } for (int i = 1; i <= n; i++) {// printf("%I64d ", dist[i]); insert(dist[i]); }// printf("\n"); for (int i = 1; i <= n; i++) { cur[i] = 1; ll t = query(dist[i], cur[i]);// printf("TEST : %I64d\n", t); heap.push(make_pair(t, i)); } memset(ans, 0xff, sizeof(ans)); for (int i = 1; i <= 200000 && i <= (ll)n * (n - 1); i++) { pair<ll, int> t = heap.top(); heap.pop(); ans[i] = t.first; cur[t.second]++; if (cur[t.second] < n) { ll res = query(dist[t.second], cur[t.second]);// printf("%d, %I64d, Rank %d: %I64d\n", t.second, dist[t.second], cur[t.second], res); heap.push(make_pair(res, t.second)); } } int q; scanf("%d", &q); for (int i = 1; i <= q; i++) { int k; scanf("%d", &k); printf("%I64d\n", ans[k]); } } return 0;}
0 0
- [HDU 4776 Ants] Trie异或+预处理
- hdu 4776 Ants (2013 杭州 现场赛) 树上预处理 trie树
- hdu 4776 Ants Trie树+乱搞
- hdu 4776 Ants
- [HDU 5536] Chip Factory (trie树+异或)
- HDU 5536 Chip Factory——Trie + 异或运算
- HDU 4776 Ants tire+优先队列
- 异或树 异或+二进制Trie
- CSUOJ 1216 异或最大值 (01Trie)
- 【bzoj3689】异或之 trie+堆
- 【bzoj3689】【异或之】【trie树+堆】
- 【BZOJ 3689】异或之 trie+堆
- BZOJ 4260 REBXOR 异或Trie+dp
- [Trie树] BZOJ3689: 异或之
- 01Trie求最大异或
- CSU 1216 异或最大值 01trie
- CSU 1216 异或最大值(01Trie)
- hdu 4776 Ants 杭州现场赛G题
- 求哈弗曼编码
- hdu 1874 dijsktra(mlogn) +bellmanford
- nginx send back content post by client
- 设置字体相关命令
- <图形图像,动画,多媒体> 读书笔记 --- 音效
- [HDU 4776 Ants] Trie异或+预处理
- 寻找阿里巴巴:杨致远完成硅谷史上最赚钱赌博
- 【无限互联】SDWebImage图片缓存流程分析
- c++命令提示符窗口下打印指定大小的菱形代码
- 找到IAR 6.2/6.3编译以前项目的出一大堆错误的原因了
- Intent
- HDU-#4786 Fibonacci Tree(最大最小生成树)
- 不能错过的徒步欢乐:从秦皇岛到北戴河
- C语言深度剖析---内存泄露