hdu 4757 Tree 南京网络赛 1010
2013-10-07 13:00
323 查看
可持久化字典树,每个节点存一棵根节点到它的节点构成的字典树,利用父节点的信息来构树。查询的时候通过最近公共祖先,查询的两个点,三个点的共同信息可以得到两点路径除公共祖先外的点构成的字典树的情况,从而得出最优解。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=1e5+9,maxm=2e6; int a[maxn],f[maxn]; int n,m; bool visit[maxn]; struct { int from,to,w,fa; }qry[maxn]; struct ED { int head[maxn],lon; struct { int next,to,from,id; }e[maxn<<1]; void clear() { memset(head,-1,sizeof(head)); lon=0; } void add(int from,int to,int id=0) { e[++lon].to=to; e[lon].from=from; e[lon].next=head[from]; e[lon].id=id; head[from]=lon; } }edge[2]; struct T { int lon,root[maxn]; struct { int to[2],son; }node[maxm]; void clear() { root[0]=lon=0; for(int i=0;lon<150000;i++) { node[i].to[0]=++lon; node[i].to[1]=++lon; node[i].son=0; } } void insert(int t,int now) { int r=root[t]; node[++lon]=node[r]; r=root[now]=lon; for(int i=16;i>=0;i--) { int u=(1<<i&a[now])>0; node[++lon]=node[node[r].to[u]]; r=node[r].to[u]=lon; node[r].son++; } } }tr; int find(int x) { if(f[x]!=x) f[x]=find(f[x]); return f[x]; } void merge(int a,int b) { f[find(b)]=find(a); } void dfs(int t,int from) { visit[t]=1; for(int k=edge[1].head[t];k!=-1;k=edge[1].e[k].next) { int u=edge[1].e[k].to; int id=edge[1].e[k].id; if(visit[u]) qry[id].fa=find(u); } for(int k=edge[0].head[t];k!=-1;k=edge[0].e[k].next) { int u=edge[0].e[k].to; if(u==from) continue; dfs(u,t); } merge(from,t); } void getlca() { memset(visit,0,sizeof(visit)); for(int i=1;i<=n;i++) f[i]=i; dfs(1,0); } void built(int t,int from) { for(int k=edge[0].head[t];k!=-1;k=edge[0].e[k].next) { int u=edge[0].e[k].to; if(u==from) continue; tr.insert(t,u); built(u,t); } } inline int get(int r,int u) { return tr.node[tr.node[r].to[u]].son; } int ask(int t) { int ans=0; int s1=qry[t].from,s2=qry[t].to,s3=qry[t].fa,w=qry[t].w; int r1=tr.root[s1],r2=tr.root[s2],r3=tr.root[s3]; for(int i=16;i>=0;i--) { int u=(1<<i&w)>0; u^=1; if(get(r1,u)+(get(r2,u))>get(r3,u)*2) ans+=(1<<i); else u^=1; r1=tr.node[r1].to[u]; r2=tr.node[r2].to[u]; r3=tr.node[r3].to[u]; } ans=max(ans,a[s3]^w); return ans; } void solve() { for(int i=1;i<=m;i++) { cout<<ask(i)<<endl;; } } int main() { // freopen("in.txt","r",stdin); while(scanf("%d %d",&n,&m)!=EOF) { edge[0].clear(); edge[1].clear(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1,from,to;i<n;i++) { scanf("%d %d",&from,&to); edge[0].add(from,to); edge[0].add(to,from); } for(int i=1,from,to,w;i<=m;i++) { scanf("%d %d %d",&from,&to,&w); qry[i].from=from; qry[i].to=to; qry[i].w=w; edge[1].add(from,to,i); edge[1].add(to,from,i); } getlca(); tr.clear(); edge[0].add(0,1); built(0,-1); solve(); } return 0; }
相关文章推荐
- HDU 4757 Tree 可持久化trie+lca
- hdu 4757 Tree(可持久化字典树)
- Hdu 5493 合肥网络赛 1010 Queue
- hdu 4751 Divide Groups 2013南京网络赛
- hdu 4276 The Ghost Blows Light 区域网络赛 1010 树上背包+spfa
- hdu-4757-Tree-树链剖分+可持久化字典树
- hdu 4756 Install Air Conditioning(2013南京网络赛)
- 【HDU - 4757】Tree 【LCA+持久化01 Trie】
- hdu 4757 Tree(可持久化字典树)
- 【2017青岛网络赛】1010 hdu 6215 Brute Force Sorting 双向链表+队列
- LCT link-cut tree Hdu 5002 Tree 2014鞍山网络赛
- HDU 4757 Tree
- HDU 4757 Tree (倍增算法求LCA + 可持久化Trie树)
- HDU 4757 Tree(可持续化字典树,lca)
- hdu 4750 Count The Pairs (2013南京网络赛)
- hdu 4757 Tree(可持久化Trie)
- HDU 4758 Walk Through Squares (2013南京网络赛1011题,AC自动机+DP)
- hdu 5446 长春区域赛网络赛1010 Unknown Treasure(lucas定理+中国剩余定理+移位乘法)
- HDU 4750 Count The Pairs (2013南京网络赛1003题,并查集)
- HDU 4757 Tree