hdu 4757 Tree(可持久化Trie)
来源:互联网 发布:mac 显示隐藏的文件夹 编辑:程序博客网 时间:2024/05/16 06:19
题意:给出一棵树,每个点上有权值,有m组询问,每次询问从x到y的路径上的权值与z异或的最大值为多少。
思路:把每个点的权值用二进制表示,然后插入Trie。利用可持久化Trie可以查询历史信息的特点,每个节点保存从当前点到根节点的Trie。对于每个查询,在Trie中查询,对于每一位,寻找与z对应位相反的分支,如果有,结果res|=(1<<i),继续查询,否则,查找与z对应位相同的分支。
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<set>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=100000+10;const int maxm=3000000+10;const int lev=15;int ch[maxm][2],sum[maxm],size;int root[maxn];int Newnode(int val){ size++; ch[size][0]=ch[size][1]=0; sum[size]=val; return size;}int Insert(int x,int val,int dep){ int rt=Newnode(sum[x]+1); if(dep==-1) return rt; int d=(val>>dep)&1; ch[rt][d^1]=ch[x][d^1]; ch[rt][d]=Insert(ch[x][d],val,dep-1); return rt;}int query(int x,int y,int val){ int res=0; for(int i=lev;i>=0;--i) { int d=(val>>i)&1; int tmp=sum[ch[y][d^1]]-sum[ch[x][d^1]]; if(tmp>0) res|=(1<<i); else d^=1; x=ch[x][d^1];y=ch[y][d^1]; } return res;}struct Edge{ int v,next; Edge(){}; Edge(int vv,int nx){v=vv;next=nx;}}edges[maxn<<1];int head[maxn],pa[maxn],father[maxn],nEdge,n,m;vector<pair<int,int> >querys[maxn];int ans[maxn],w[maxn],z[maxn];bool vis[maxn];void Init(){ ch[0][0]=ch[0][1]=sum[0]=size=0; memset(root,0,sizeof(root)); memset(head,0xff,sizeof(head)); memset(vis,0,sizeof(vis)); nEdge=-1;father[1]=0; for(int i=0;i<=n;++i) querys[i].clear();}int Find(int x){ return x==pa[x]?x:pa[x]=Find(pa[x]);}void AddEdges(int u,int v){ edges[++nEdge]=Edge(v,head[u]); head[u]=nEdge; edges[++nEdge]=Edge(u,head[v]); head[v]=nEdge;}void dfs(int u,int fa){ pa[u]=u;vis[u]=true; root[u]=Insert(root[father[u]],w[u],lev); int sz=querys[u].size(); int v,pos,lca; for(int i=0;i<sz;++i) { v=querys[u][i].first;pos=querys[u][i].second; if(vis[v]) { lca=Find(v); ans[pos]=max(query(root[lca],root[u],z[pos]),query(root[lca],root[v],z[pos])); ans[pos]=max(w[lca]^z[pos],ans[pos]); } } for(int k=head[u];k!=-1;k=edges[k].next) { v=edges[k].v; if(v==fa) continue; father[v]=u; dfs(v,u); pa[v]=u; }}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&m)) { Init(); for(int i=1;i<=n;++i) scanf("%d",&w[i]); int u,v; for(int i=1;i<n;++i) { scanf("%d%d",&u,&v); AddEdges(u,v); } for(int i=1;i<=m;++i) { scanf("%d%d%d",&u,&v,&z[i]); querys[u].push_back(make_pair(v,i)); querys[v].push_back(make_pair(u,i)); } dfs(1,-1); for(int i=1;i<=m;++i) printf("%d\n",ans[i]); } return 0;}
0 0
- hdu 4757 Tree(可持久化Trie)
- HDU 4757 Tree 可持久化trie+lca
- HDU 4757 可持久化trie树
- HDU 4757 Tree (倍增算法求LCA + 可持久化Trie树)
- HDU 6191 Query on A Tree 可持久化trie + dfs建树 || 启发式合并trie
- HDU 4757 可持久化字典树(Trie)
- HDU-5801 可持久化Trie树
- HDU 6191 Query on A Tree (dfs序+可持久化01Trie)
- 可持久化trie
- [HDU4757][可持久化Trie][LCA]Tree[好题]
- hdu 4757 Tree(可持久化字典树)
- hdu-4757-Tree-树链剖分+可持久化字典树
- Hdu-4757 Tree(可持久化字典树)
- hdu 4757 Tree(可持久化字典树)
- hdu 6191 可持久化trie||线段树套trie||trie启发式合并
- [BZOJ3261]-可持久化trie
- HDU 3333 Turing Tree 可持久化线段树
- bzoj 2741 分块 + 可持久化trie
- centos VI编辑器配置文件
- linux shell学习
- Private strand flush not complete
- Computer Vision:a Modern Approach 摘抄笔记——Chapter 9:Segmentation by Clustering
- ExtJs中日期的格式化处理
- hdu 4757 Tree(可持久化Trie)
- 别错把需求当市场
- 这是怎么了
- 数据库在线重做日志崩溃
- linux常用命令介绍
- 再谈让C++更像C#:C#内存泄露问题
- OpenCV2.4.5 和VS2008配置
- mysql区分大小写配置lower_case_table_names
- [转]结构体边界对齐问题