您的位置:首页 > 理论基础 > 计算机网络

2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor(LCA+K级父亲暴力卡过)

2017-09-22 19:15 477 查看

题目链接:2017 ACM-ICPC 亚洲区(西安赛区)网络赛   G. Xor

题意:

给你一棵有n个节点的树,然后有Q个询问,每次询问给出两个点x,y,k。将x->y路径上经过的点放进一个数组a里,将询问[0],a[k],a[2*k],a[m*k]的值异或起来的值为多少。

题解:

预处理lca和k=1的答案,k>1的用倍增暴力往上跳,然后就完了,不过有点慢,需要加个读入挂才能过。

 

1 #include<bits/stdc++.h>
2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
3 using namespace std;
4
5 const int N=5e5+5,DEG=17;
6 int ed,g
,nxt[2*N],v[2*N],fa
[DEG],dep
,val
;
7 int a
,n,q,vis
,TIM;
8
9 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
10
11 void dfs(int u,int pre){
12     dep[u]=dep[pre]+1,fa[u][0]=pre,val[u]=val[pre]^a[u];
13     F(i,1,DEG-1)fa[u][i]=fa[fa[u][i-1]][i-1];
14     for(int i=g[u];i;i=nxt[i])if(v[i]!=pre)dfs(v[i],u);
15 }
16
17 int LCA(int a,int b){
18     if(dep[a]>dep[b])a^=b,b^=a,a^=b;
19     if(dep[a]<dep[b])F(i,0,DEG-1)if((dep[b]-dep[a])&(1<<i))b=fa[b][i];
20     if(a!=b)for(int i=DEG-1;i<0?a=fa[a][0]:0,i>=0;i--)
21     if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
22     return a;
23 }
24
25
26 int kth_father(int x,int k)
27 {
28     while(k)x=fa[x][__builtin_ctz(k&-k)],k^=k&-k;
29     return x;
30 }
31
32 void solve(int x,int y,int k)
33 {
34     TIM++;
35     if(x==y){printf("%d\n",a[x]);return;}
36     int lca=LCA(x,y);
37     if(k==1)
38     {
39         if(lca==x)printf("%d\n",val[y]^val[lca]^a[lca]);
40         else if(lca==y)printf("%d\n",val[x]^val[lca]^a[lca]);
41         else printf("%d\n",val[y]^val[x]^a[lca]);
42         return;
43     }
44     int now=kth_father(x,k),ans=a[x],pre=now;
45     vis[x]=TIM;
46     while(dep[now]>=dep[lca])
47     {
48         if(vis[now]!=TIM)ans^=a[now],vis[now]=TIM;
49         pre=now,now=kth_father(now,k);
50     }
51     int Long=dep[x]+dep[y]-2*dep[lca]+1;
52     if((Long-1)<k){printf("%d\n",ans);return;}
53     int last=(Long-1)/k*k+1;
54     int dis=Long-last;
55     now=kth_father(y,dis);
56     if(vis[now]!=TIM&&dep[now]>=dep[lca])ans^=a[now],vis[now]=TIM;
57     now=kth_father(now,k);
58     while(dep[now]>=dep[lca])
59     {
60         if(vis[now]!=TIM)ans^=a[now],vis[now]=TIM;
61         now=kth_father(now,k);
62     }
63     printf("%d\n",ans);
64 }
65
66 int main(){
67     while(read(n),read(q))
68     {
69         int x,y,k;
70         F(i,1,n)g[i]=0;ed=0;
71         F(i,2,n)
72         {
73             read(x),read(y);
74             adg(x,y),adg(y,x);
75         }
76         F(i,1,n)read(a[i]);
77         dfs(1,0);
78         F(i,1,q)
79         {
80             read(x),read(y),read(k);
81             solve(x,y,k);
82         }
83     }
84     return 0;
85 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐