zoukankan      html  css  js  c++  java
  • bzoj2819: Nim(博弈+树剖)

    2819: Nim

    题目:传送门 


    题解:

       很久之前学博弈的时候看过的一道水题,其实算不上博弈吧...

       直接套上一个裸的树剖啊,把路径上的点值全都xor(xor满足结合率所以就不管那么多随便搞啦)

       dog B 肉老师,竟然不告诉我它卡常,搞得我TLE几百年

        


    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<iostream>
      7 using namespace std;
      8 inline int read()
      9 {
     10     int f=1,x=0;char ch;
     11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return f*x;
     14 }
     15 struct node
     16 {
     17     int x,y,next;
     18 }a[1110000];int len,last[510000];
     19 inline void ins(int x,int y)
     20 {
     21     len++;a[len].x=x;a[len].y=y;
     22     a[len].next=last[x];last[x]=len;
     23 }
     24 struct trnode
     25 {
     26     int l,r,c,lc,rc;
     27 }tr[1110000];int trlen;
     28 inline void bt(int l,int r)
     29 {
     30     int now=++trlen;
     31     tr[now].l=l;tr[now].r=r;tr[now].c=0;
     32     tr[now].lc=tr[now].rc=-1;
     33     if(l<r)
     34     {
     35         int mid=(tr[now].l+tr[now].r)/2;
     36         tr[now].lc=trlen+1;bt(l,mid);
     37         tr[now].rc=trlen+1;bt(mid+1,r);
     38     }
     39 }
     40 inline void change(int now,int p,int c)
     41 {
     42     if(tr[now].l==tr[now].r){tr[now].c=c;return ;}
     43     int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
     44     if(p<=mid)change(lc,p,c);
     45     else change(rc,p,c);
     46     tr[now].c=tr[lc].c^tr[rc].c;
     47 }
     48 inline int getsum(int now,int l,int r)
     49 {
     50     if(tr[now].l==l && r==tr[now].r)return tr[now].c;
     51     int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2;
     52     if(r<=mid)return getsum(lc,l,r);
     53     else if(mid+1<=l)return getsum(rc,l,r);
     54     return getsum(lc,l,mid)^getsum(rc,mid+1,r);
     55 }
     56 int n,fa[510000],son[510000],dep[510000],tot[510000];
     57 inline void pre_tree_node(int x)
     58 {
     59     son[x]=0;tot[x]=1;
     60     for(register int k=last[x];k;k=a[k].next)
     61     {
     62         int y=a[k].y;
     63         if(y!=fa[x])
     64         {
     65             dep[y]=dep[x]+1;
     66             fa[y]=x;
     67             pre_tree_node(y);
     68             if(tot[y]>tot[son[x]])son[x]=y;
     69             tot[x]+=tot[y];
     70         }
     71     }
     72 }
     73 int top[510000],ys[510000],id,tp;
     74 inline void pre_tree_edge(int x)
     75 {
     76     int tt=tp;top[x]=tp;ys[x]=++id;
     77     if(son[x]!=0)pre_tree_edge(son[x]);
     78     for(register int k=last[x];k;k=a[k].next)
     79     {
     80         int y=a[k].y;
     81         if(y!=son[x] && y!=fa[x])
     82         {
     83             tp=y;
     84             pre_tree_edge(y);
     85             tp=tt;
     86         }
     87     }
     88 }
     89 int sol(int x,int y)
     90 {
     91     int ans=0,tx=top[x],ty=top[y];
     92     while(tx!=ty)
     93     {
     94         if(dep[tx]>dep[ty])swap(tx,ty),swap(x,y);
     95         ans^=getsum(1,ys[ty],ys[y]);
     96         y=fa[ty];ty=top[y];
     97     }
     98     if(x==y)return ans^getsum(1,ys[x],ys[x]);
     99     else
    100     {
    101         if(dep[x]>dep[y])swap(x,y);
    102         return ans^getsum(1,ys[x],ys[y]);
    103     }
    104 }
    105 int st[510000],Q;
    106 char s[3];
    107 int main()
    108 {
    109     //freopen("a.in","r",stdin);freopen("a.out","w",stdout);
    110     n=read();for(int i=1;i<=n;++i)st[i]=read();
    111     len=0;memset(last,0,sizeof(last));
    112     for(register int i=1;i<n;++i)
    113     {
    114         int x=read(),y=read();
    115         ins(x,y);ins(y,x);
    116     }
    117     fa[1]=0;dep[1]=0;pre_tree_node(1);
    118     id=0;tp=1;pre_tree_edge(1);
    119     trlen=0;bt(1,id);
    120     for(register int i=1;i<=n;++i)change(1,ys[i],st[i]);
    121     Q=read();
    122     while(Q--)
    123     {
    124         scanf("%s",s+1);int x=read(),y=read();
    125         if(s[1]=='Q')
    126         {
    127             if(sol(x,y)!=0)printf("Yes
    ");
    128             else printf("No
    ");
    129         }
    130         else change(1,ys[x],y);
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    2.12 使用@DataProvider
    2.11 webdriver中使用 FileUtils ()
    Xcode8 添加PCH文件
    The app icon set "AppIcon" has an unassigned child告警
    Launch Image
    iOS App图标和启动画面尺寸
    iPhone屏幕尺寸、分辨率及适配
    Xcode下载失败 使用已购项目页面再试一次
    could not find developer disk image
    NSDate与 NSString 、long long类型的相互转化
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8808559.html
Copyright © 2011-2022 走看看