HDU
来源:互联网 发布:网络在线教育迎着 编辑:程序博客网 时间:2024/06/06 10:49
点我看题
题意:给出一颗有n个结点的树,每个结点有一个权值,m个询问,问x与以u为根的子树的每一个结点进行异或的最大值是多少。
分析:可持久化字典树,先合并每一颗的字典树,然后贪心查找。
参考代码:
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<vector>#include<iostream>using namespace std;#define mem(a,b) memset(a,b,sizeof(a))typedef long long LL;const int maxn = 1e5+10;int n,q;int a[maxn];vector<int> g[maxn];//字典树int ch[maxn<<6][2],root[maxn<<2],sz;void Init(){ sz = 0; mem(ch,0); mem(root,0);}void Insert( int u, int val){ root[u] = ++sz; int rt = sz; for( int i = 30; i >= 0; i--) { int id = (val>>i)&1; if( !ch[rt][id]) ch[rt][id] = ++sz; rt = ch[rt][id]; }}int Merge( int u, int v){ if( u == 0) return v; if( v == 0) return u; int rt = ++sz; ch[rt][0] = Merge(ch[u][0],ch[v][0]); ch[rt][1] = Merge(ch[u][1],ch[v][1]); return rt;}void dfs( int u, int pre){ root[u] = ++sz; Insert(u,a[u]); for( int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if( v != pre) { dfs(v,u); root[u] = Merge(root[u],root[v]); } }}LL Query( int u, int x){ int rt = root[u]; LL ret = 0; for( int i = 30; i >= 0; i--) { int id = (x>>i)&1; if( ch[rt][!id]) { ret += (1<<i); rt = ch[rt][!id]; } else rt = ch[rt][id]; } return ret;}int main(){ while( ~scanf("%d%d",&n,&q)) { Init(); for( int i = 1; i <= n; i++) { scanf("%d",&a[i]); g[i].clear(); } int v; for( int i = 1; i < n; i++) { scanf("%d",&v); g[v].push_back(i+1); g[i+1].push_back(v); } dfs(1,0); int u,x; while( q--) { scanf("%d%d",&u,&x); printf("%lld\n",Query(u,x)); } } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- c#两个对象,同属性赋值
- Linux export 命令
- Android Studio 去掉标题栏
- Codeforces 846D Monitor(二维前缀和)
- 剑指offer-3-Python实现二维数组的查找
- HDU
- 2017 Multi-University Training Contest No.4
- linux 通过哪个命令可以查看某个服务及其端口、进程号
- C-通用内存交换函数
- 【LeetCode算法练习(C语言)】Two Sum
- POJ 3233 Matrix Power Series(矩阵快速幂+二分求解)
- Ubuntu14.04云服务器使用wordpress搭建个人博客的个人总结
- fpga图像处理
- a 标签中如何设置其宽度和高度