TJOI2018 异或
发布时间:2020-12-15 18:19:30 所属栏目:安全 来源:网络整理
导读:题目链接:戳我 可持久化01trie+树链剖分 其实序列上的大家应该都会做,这个题还不过是把序列上的放到了树上而已。多来一个树剖就可以解决。 dummyummy说可以不用树剖写。。可是我还是不怎么会。。。等他写完了我再放那种解法的吧。。。 代码如下: #include
题目链接:戳我可持久化01trie+树链剖分其实序列上的大家应该都会做,这个题还不过是把序列上的放到了树上而已。多来一个树剖就可以解决。 dummyummy说可以不用树剖写。。可是我还是不怎么会。。。等他写完了我再放那种解法的吧。。。 代码如下: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define MAXN 200010 using namespace std; int n,m,t,dfn,tot; int head[MAXN<<1],wt[MAXN],rt[MAXN],ch[MAXN*32][2],cnt[MAXN*32]; int siz[MAXN],id[MAXN],w[MAXN],fa[MAXN],son[MAXN],top[MAXN],dep[MAXN]; struct Edge{int nxt,to;}edge[MAXN<<1]; inline void add(int from,int to) { edge[++t].nxt=head[from],edge[t].to=to,head[from]=t; edge[++t].nxt=head[to],edge[t].to=from,head[to]=t; } inline void dfs1(int x,int pre) { siz[x]=1; fa[x]=pre; dep[x]=dep[pre]+1; int maxx=-1; for(int i=head[x];i;i=edge[i].nxt) { int v=edge[i].to; if(v==pre) continue; dfs1(v,x); siz[x]+=siz[v]; if(siz[v]>maxx) maxx=siz[v],son[x]=v; } } inline void dfs2(int x,int topf) { top[x]=topf; id[x]=++dfn; w[dfn]=wt[x]; if(son[x]) dfs2(son[x],topf); for(int i=head[x];i;i=edge[i].nxt) { int v=edge[i].to; if(v==fa[x]||v==son[x]) continue; dfs2(v,v); } } inline void insert(int x,int f,int sum) { for(int i=31;i>=0;i--) { int v=((sum>>i)&1); ch[x][!v]=ch[f][!v]; ch[x][v]=++tot; cnt[ch[x][v]]=cnt[ch[f][v]]+1; x=ch[x][v],f=ch[f][v]; } } inline int query(int f,int x,int sum) { int cur_ans=0; for(int i=31;i>=0;i--) { int v=((sum>>i)&1); if(cnt[ch[x][!v]]>cnt[ch[f][!v]]) { cur_ans+=(1<<i); x=ch[x][!v],f=ch[f][!v]; } else x=ch[x][v],f=ch[f][v]; } return cur_ans; } inline int solve(int x,int y,int z) { int cur_ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); cur_ans=max(cur_ans,query(rt[id[top[x]]-1],rt[id[x]],z)); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); cur_ans=max(cur_ans,query(rt[id[x]-1],rt[id[y]],z)); return cur_ans; } int main() { #ifndef ONLINE_JUDGE freopen("ce.in","r",stdin); #endif scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&wt[i]); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); } dfs1(1,0); dfs2(1,1); rt[0]=++tot; insert(rt[0],0); //for(int i=1;i<=n;i++) printf("i=%d fa=%d w=%dn",i,fa[i],w[i]); //for(int i=1;i<=n;i++) printf("i=%d id=%d siz=%dn",id[i],siz[i]); for(int i=1;i<=n;i++) rt[i]=++tot,insert(rt[i],rt[i-1],w[i]); //for(int i=1;i<=n;i++) printf("rt[%d]=%dn",rt[i]); for(int i=1;i<=m;i++) { int op,x,y,z; scanf("%d",&op); if(op==1) { scanf("%d%d",&x,&y); //printf("op=%d x=%d y=%dn",op,y); printf("%dn",rt[id[x]+siz[x]-1],y)); } else { scanf("%d%d%d",&y,&z); //printf("op=%d x=%d y=%d z=%dn",z); printf("%dn",solve(x,z)); } } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |