首页 > 代码库 > 【BZOJ】【2819】NIM
【BZOJ】【2819】NIM
这题……咋说捏,其实是一道披着博弈论外衣的树上操作问题……
随便用dfs序或者树链剖分转成序列,然后查询路径上的所有点的NIM和(异或和)就行了,毕竟除了是在树上以外,就是裸的NIM问题。
树链剖分:一开始把线段树写跪了,然后输出“Yes”和“No”的时候全部大写了,再然后发现线段树空间开小了……
代码如下:
1 //BZOJ 2819 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 #define pb push_back 12 using namespace std; 13 const int N=500010; 14 #define debug 15 int n,a[N],t[N<<2],fa[N],top[N],dep[N],son[N],size[N],tid[N],cnt=0; 16 vector<int>G[N]; 17 bool vis[N]; 18 19 #define mid (l+r>>1) 20 #define L (o<<1) 21 #define R (o<<1|1) 22 void updata(int o,int l,int r,int pos,int v){ 23 if (l==r) t[o]=v; 24 else{ 25 if (pos<=mid) updata(L,l,mid,pos,v); 26 else updata(R,mid+1,r,pos,v); 27 t[o]=t[L]^t[R]; 28 } 29 } 30 31 int ql,qr,ans=0; 32 void query_it(int o,int l,int r){ 33 if (ql<=l && qr>=r) ans^=t[o]; 34 else{ 35 if (ql<=mid) query_it(L,l,mid); 36 if (qr>mid) query_it(R,mid+1,r); 37 } 38 } 39 //segment tree end 40 41 void dfs(int x,int f,int deep){ 42 int y,maxsize=0; 43 vis[x]=1; fa[x]=f; dep[x]=deep; size[x]=1; son[x]=0; 44 rep(i,G[x].size()){ 45 y=G[x][i]; 46 if (vis[y]) continue; 47 dfs(y,x,deep+1); 48 size[x]+=size[y]; 49 if (size[y]>maxsize) maxsize=size[y],son[x]=y; 50 } 51 } 52 53 void connect(int x,int f){ 54 tid[x]=++cnt; 55 top[x]=f; vis[x]=1; 56 if (son[x]) connect(son[x],f); 57 rep(i,G[x].size()){ 58 int y=G[x][i]; 59 if (!vis[y]) connect(y,y); 60 } 61 } 62 63 void query(int x,int y){ 64 while(top[x]!=top[y]){ 65 if (dep[top[x]]<dep[top[y]]) swap(x,y); 66 ql=tid[top[x]]; qr=tid[x]; 67 query_it(1,1,n); 68 x=fa[top[x]]; 69 } 70 if (dep[x]>dep[y]) swap(x,y); 71 ql=tid[x]; qr=tid[y]; 72 query_it(1,1,n); 73 } 74 75 int main(){ 76 // freopen("file.in","r",stdin); 77 scanf("%d",&n); 78 F(i,1,n) scanf("%d",&a[i]); 79 int x,y; 80 F(i,2,n){ 81 scanf("%d%d",&x,&y); 82 G[x].pb(y); 83 G[y].pb(x); 84 } 85 dfs(1,0,1); 86 memset(vis,0,sizeof vis); 87 connect(1,1); 88 F(i,1,n) updata(1,1,n,tid[i],a[i]); 89 int q; 90 scanf("%d",&q); 91 char cmd[3]; 92 F(i,1,q){ 93 scanf("%s%d%d",cmd,&x,&y); 94 if (cmd[0]==‘Q‘){ 95 ans=0; 96 query(x,y); 97 printf(ans ? "Yes\n" : "No\n"); 98 } 99 else updata(1,1,n,tid[x],y);100 }101 return 0;102 }
【BZOJ】【2819】NIM
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。