bzoj2819: Nim
这岂不是一眼树剖??
WTF怎么R了。discuss不是说不会爆吗。。
妈也手写栈?
WTF怎么WA了,mdzz数组, WTF怎么MLE了。。
蛤,还能TLE?我去还卡常。。。OKOK
就是沙茶题啊
但是他给我展示了各种报错的魅力
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n; struct node { int x,y,next; }a[1100000];int len,last[510000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } /* void pre_tree_node(int x) { son[x]=0;tot[x]=0; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(fa[x]!=y) { fa[y]=x; dep[y]=dep[x]+1; pre_tree_node(y); if(tot[son[x]]<tot[y])son[x]=y; tot[x]+=tot[y]; } } } void pre_tree_edge(int x,int tp) { ys[x]=++z;tp[x]=tp; if(son[x]!=0)pre_tree_edge(son[x],tp); for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(fa[x]!=y&&son[x]!=y) pre_tree_edge(y,y); } } dfs版*/ int top,sta[1100000],cur[510000];//cur表示当前点枚举到那一条边 int dep[510000],tot[510000],fa[510000],son[510000]; void pre_tree_node() { for(int i=1;i<=n;i++)cur[i]=last[i]; top=0;sta[++top]=1; tot[1]=1;dep[1]=1; while(top!=0) { int x=sta[top]; int k=cur[x]; if(a[k].y==fa[x])k=cur[x]=a[cur[x]].next; if(k!=0) { int y=a[k].y; sta[++top]=y; tot[y]=1;dep[y]=dep[x]+1;fa[y]=x; cur[x]=a[k].next; } else//该点的子节点已访问完毕,回溯 { top--; if(fa[x]!=0) { tot[fa[x]]+=tot[x]; if(tot[son[fa[x]]]<tot[x])son[fa[x]]=x; } } } } int z,ys[510000],tp[510000]; bool v[510000]; void pre_tree_edge() { for(int i=1;i<=n;i++)cur[i]=last[i]; memset(v,false,sizeof(v)); top=0;sta[++top]=1; ys[1]=++z;tp[1]=1; while(top!=0) { int x=sta[top]; if(v[x]==false)//先访问重儿子 { v[x]=true; if(son[x]!=0) { sta[++top]=son[x]; ys[son[x]]=++z;tp[son[x]]=tp[x]; } } else { int k=cur[x]; if(a[k].y==fa[x]||a[k].y==son[x])k=cur[x]=a[cur[x]].next; if(a[k].y==fa[x]||a[k].y==son[x])k=cur[x]=a[cur[x]].next; if(k!=0) { int y=a[k].y; sta[++top]=y; ys[y]=++z;tp[y]=y; cur[x]=a[k].next; } else top--; } } } //手写栈,非递归版 //---------composition---------------- struct seqtree { int l,r,lc,rc,c; }tr[1100000];int trlen; int gb[1100000]; void bt(int l,int r) { trlen++;int now=trlen; tr[now].l=l;tr[now].r=r; if(l==r) { tr[now].lc=tr[now].rc=-1; tr[now].c=gb[l]; } else { int mid=(l+r)/2; tr[now].lc=trlen+1;bt(l,mid); tr[now].rc=trlen+1;bt(mid+1,r); tr[now].c=(tr[tr[now].lc].c^tr[tr[now].rc].c); } } //--------init tree----------- void change(int now,int p,int c) { if(tr[now].l==tr[now].r){tr[now].c=c;return ;} int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(p<=mid)change(lc,p,c); else change(rc,p,c); tr[now].c=(tr[lc].c^tr[rc].c); } int getyh(int now,int l,int r) { if(tr[now].l==l&&tr[now].r==r)return tr[now].c; int mid=(tr[now].l+tr[now].r)/2; int lc=tr[now].lc,rc=tr[now].rc; if(r<=mid)return getyh(lc,l,r); else if(mid+1<=l)return getyh(rc,l,r); else return (getyh(lc,l,mid)^getyh(rc,mid+1,r)); } int solve(int x,int y) { int tx=tp[x],ty=tp[y]; int ans=0; while(tx!=ty) { if(dep[tx]>dep[ty]) swap(x,y), swap(tx,ty); ans^=getyh(1,ys[ty],ys[y]); y=fa[ty];ty=tp[y]; } if(dep[x]>dep[y])swap(x,y); ans^=getyh(1,ys[x],ys[y]); if(ans!=0)return 1; else return 0; } int stone[510000]; char ss[10]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&stone[i]); int x,y; len=0;memset(last,0,sizeof(last)); for(int i=1;i<n;i++) { scanf("%d%d",&x,&y); ins(x,y);ins(y,x); } pre_tree_node(); pre_tree_edge(); for(int i=1;i<=n;i++)gb[ys[i]]=stone[i]; bt(1,n);trlen=0; int m=0; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%s%d%d",ss+1,&x,&y); if(ss[1]=='Q') { if(solve(x,y)==1)printf("Yes\n"); else printf("No\n"); } else { stone[x]=y; change(1,ys[x],stone[x]); } } return 0; }
pain and happy in the cruel world.