2017.9.4 Nim 思考记录

来源:互联网 发布:java 判断是不是汉字 编辑:程序博客网 时间:2024/04/25 08:44

只要知道nim的结论   这题就是链剖板子题、1A

注意bzoj 的  换行符是     \r!!      \r!!      \r!!

就说一下链剖的易错点吧:

1、记录父节点、sz、深度

2、当前点对应到链剖序

3、比较top深度,

4、while后面一定会执行一次 区间操作!




链剖(nlog^2n),vfk卡递归的邪恶想法被bzoj的评测机制抹杀了

码(1800ms卡过):

#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define zuo o<<1,l,mid#define you o<<1|1,mid+1,r#define N 600005int tot,ans,hou[N<<1],xia[N],n,zhong[N<<1],s[N],q,v[N<<2],fa[N],top[N],dis[N],sz[N],bj[N],op,hson[N],a,b,c;char ch;void jian(int x,int y){++tot,hou[tot]=xia[x],xia[x]=tot,zhong[tot]=y;}void jia(int x,int y){jian(x,y);jian(y,x);}void up(int o){v[o]=v[o<<1]^v[o<<1|1];}void dfs1(int o,int fu,int d){int i; fa[o]=fu;   sz[o]=1;   dis[o]=d;   for(i=xia[o];i!=-1;i=hou[i])   {   int nd=zhong[i];   if(nd==fu)continue;   dfs1(nd,o,d+1);   sz[o]+=sz[nd];   if(sz[hson[o]]<sz[nd])hson[o]=nd;}}void dfs2(int o,int tap,int fu){int i;top[o]=tap;bj[o]=++tot;if(hson[o])dfs2(hson[o],tap,o);for(i=xia[o];i!=-1;i=hou[i]){int nd=zhong[i];if(nd==fu||nd==hson[o])continue;dfs2(nd,nd,o);}}void cha(int o,int l,int r){if(l>=a&&r<=b){if(op==1)ans^=v[o];else v[o]=c;return;}int mid=(l+r)>>1;if(a<=mid)cha(zuo);if(b>mid)cha(you);if(op!=1)up(o);}int work(int x,int y){ans=0;op=1;    while(top[x]!=top[y])    {    if(dis[top[x]]<dis[top[y]])swap(x,y);a=bj[top[x]],b=bj[x];    cha(1,1,tot);    x=fa[top[x]];    }if(dis[x]<dis[y])swap(x,y);a=bj[y],b=bj[x];    cha(1,1,tot);}int main(){memset(xia,-1,sizeof(xia));int i;scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&s[i]);for(i=1;i<n;i++){scanf("%d%d",&a,&b);   jia(a,b);}tot=0;dfs1(1,1,1);dfs2(1,1,1);for(i=1;i<=n;i++){op=0;a=b=bj[i];c=s[i];cha(1,1,tot);}scanf("%d",&q);for(i=1;i<=q;i++){scanf("%c",&ch);while(ch=='\0'||ch=='\n'||ch=='\r')scanf("%c",&ch);if(ch=='C'){   scanf("%d%d",&a,&c);   a=bj[a];   b=a;   op=0;   cha(1,1,tot);}else{ scanf("%d%d",&a,&b); work(a,b);if(ans==0) printf("No\n");else printf("Yes\n");}}}


原创粉丝点击