标签:sdi names get query class har 一个 space for
关于Nim游戏,当所有堆异或起来为0时,必输,否则有必胜方法。
所以,问题就转化成了在线询问树上一条道路上点权的异或值并支持修改。
在树上的询问不好搞,所以我们使用bfs序将原树转化成一段区间。
对于一次查询,也就转化成了一段区间的异或和。
考虑一个点会影响哪个区间,已知,就是访问到它的时刻到遍历完它的所有子树之后再回来的那个时刻。
所以,我们记录一个点初次访问和离开的bfs序,在树状数组上查询即可。(查询时因为树状数组维护的是他到根的异或和,这时两点的Lca被异或掉了,所以要再异或一下Lca的值)
那么怎么处理修改呢?
因为是异或,所以对于一个点,再更新一遍它就等于把这个点删掉。所以我们用原值更新一下这个点,再用新的值更新就行了。
1 #include<bits/stdc++.h> 2 #define INTMAX 2147483647LL 3 #define PII pair<int,int> 4 #define MK make_pair 5 #define re register 6 using namespace std; 7 typedef long long ll; 8 const double Pi=acos(-1.0); 9 const int Inf=0x3f3f3f3f; 10 const int MAXN=5e5+10; 11 inline int read(){ 12 re int x=0,f=1,ch=getchar(); 13 while(!isdigit(ch))f=ch==‘-‘?-1:1,ch=getchar(); 14 while(isdigit(ch))x=x*10+ch-48,ch=getchar(); 15 return x*f; 16 } 17 inline ll readll(){ 18 re ll x=0,f=1,ch=getchar(); 19 while(!isdigit(ch))f=ch==‘-‘?-1:1,ch=getchar(); 20 while(isdigit(ch))x=x*10+ch-48,ch=getchar(); 21 return x*f; 22 } 23 24 struct Edge{ 25 int to,nxt; 26 }e[MAXN<<1]; 27 int cnt,head[MAXN]; 28 inline void add_edge(int u,int v){ 29 e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt; 30 } 31 int n,m; 32 int bse[25],BIT[MAXN]; 33 int a[MAXN]; 34 int tim,l[MAXN],r[MAXN]; 35 int dep[MAXN],fa[MAXN][25]; 36 char ch[5]; 37 inline void dfs(int x){ 38 for(int i=1;i<=20;++i) 39 if(dep[x]>=bse[i]) 40 fa[x][i]=fa[fa[x][i-1]][i-1]; 41 else 42 break; 43 l[x]=++tim; 44 for(int i=head[x],y;i;i=e[i].nxt){ 45 y=e[i].to; 46 if(y!=fa[x][0]){ 47 dep[y]=dep[x]+1;fa[y][0]=x; 48 dfs(y); 49 } 50 } 51 r[x]=tim; 52 } 53 inline int lowbit(int x){return x&(-x);} 54 inline void Update(int x,int v){for(int i=x;i<=n;i+=lowbit(i)) BIT[i]^=v;} 55 inline int Query(int x){int res=0;for(int i=x;i;i-=lowbit(i))res^=BIT[i];return res;} 56 inline int Get_lca(int x,int y){ 57 if(dep[x]<dep[y]) swap(x,y); 58 int tmp=dep[x]-dep[y]; 59 for(int i=0;i<=20;++i) 60 if(bse[i]&tmp) 61 x=fa[x][i]; 62 for(int i=20;i>=0;--i) 63 if(fa[x][i]!=fa[y][i]) 64 x=fa[x][i],y=fa[y][i]; 65 if(x==y) return x; 66 return fa[x][0]; 67 } 68 int main(){ 69 bse[0]=1;for(int i=1;i<=21;++i) bse[i]=bse[i-1]<<1; 70 n=read(); 71 for(int i=1;i<=n;++i) a[i]=read(); 72 for(int i=1,u,v;i<n;++i){ 73 u=read();v=read(); 74 add_edge(u,v); 75 add_edge(v,u); 76 } 77 dfs(1); 78 //cout<<111<<endl; 79 for(int i=1;i<=n;++i){ 80 Update(l[i],a[i]); 81 Update(r[i]+1,a[i]); 82 } 83 //cout<<2<<endl; 84 m=read(); 85 while(m--){ 86 scanf("%s",ch); 87 int x=read(),y=read(); 88 if(ch[0]==‘Q‘){ 89 int lca=Get_lca(x,y); 90 int res=Query(l[x])^Query(l[y])^a[lca]; 91 puts(res?"Yes":"No"); 92 } 93 else{ 94 Update(l[x],a[x]);Update(r[x]+1,a[x]); 95 a[x]=y; 96 Update(l[x],a[x]);Update(r[x]+1,a[x]); 97 } 98 } 99 return 0; 100 }
标签:sdi names get query class har 一个 space for
原文地址:https://www.cnblogs.com/LI-dox/p/11267234.html