• BZOJ 2819 Nim


    Description

    著名游戏设计师vfleaking,最近迷上了Nim。普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取。谁不能取谁输。这个游戏是有必胜策略的。于是vfleaking决定写一个玩Nim游戏的平台来坑玩家。
    为了设计漂亮一点的初始局面,vfleaking用以下方式来找灵感:拿出很多石子,把它们聚成一堆一堆的,对每一堆编号1,2,3,4,...n,在堆与堆间连边,没有自环与重边,从任意堆到任意堆都只有唯一一条路径可到达。然后他不停地进行如下操作:

    1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家。
    2.把堆v中的石子数变为k。

    由于vfleaking太懒了,他懒得自己动手了。请写个程序帮帮他吧。

    Input

     第一行一个数n,表示有多少堆石子。
    接下来的一行,第i个数表示第i堆里有多少石子。
    接下来n-1行,每行两个数v,u,代表v,u间有一条边直接相连。
    接下来一个数q,代表操作的个数。
    接下来q行,每行开始有一个字符:
    如果是Q,那么后面有两个数v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略。
    如果是C,那么后面有两个数v,k,代表把堆v中的石子数变为k。

    对于100%的数据:
    1≤N≤500000, 1≤Q≤500000, 0≤任何时候每堆石子的个数≤32767
    其中有30%的数据:
    石子堆组成了一条链,这3个点会导致你DFS时爆栈(也许你不用DFS?)。其它的数据DFS目测不会爆。

    注意:石子数的范围是0到INT_MAX

    Output

    对于每个Q,输出一行Yes或No,代表对询问的回答。

    Sample Input

    【样例输入】
    5
    1 3 5 2 5
    1 5
    3 5
    2 5
    1 4
    6
    Q 1 2
    Q 3 5
    C 3 7
    Q 1 2
    Q 2 4
    Q 5 3

    Sample Output

    Yes
    No
    Yes
    Yes
    Yes
    首先满足SG函数异或和为0则必败
    因为在一堆中可以任意取,所以SG[i]=a[i]
    所以就变成了查询修改异或和
    用树剖和树状数组维护
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 using namespace std;
      7 struct Node
      8 {
      9   int next,to;
     10 }edge[1000001];
     11 int head[500001],num,n,top[500001],a[500001],dep[500001],m;
     12 int c[500001],fa[500001],size[500001],son[500001],dfn[500001],cnt;
     13 int gi()
     14 {
     15   int x=0;
     16   char ch=getchar();
     17   while (ch<'0'||ch>'9') ch=getchar();
     18   while (ch>='0'&&ch<='9')
     19     {
     20       x=x*10+ch-'0';
     21       ch=getchar();
     22     }
     23   return x;
     24 }
     25 void insert(int u,int v)
     26 {
     27   num++;
     28   edge[num].next=head[u];
     29   head[u]=num;
     30   edge[num].to=v;
     31 }
     32 void add(int x,int v)
     33 {
     34   while (x<=n)
     35     {
     36       c[x]^=v;
     37       x+=(x&(-x));
     38     }
     39 }
     40 int query(int x)
     41 {
     42   int s=0;
     43   while (x)
     44     {
     45       s^=c[x];
     46       x-=(x&(-x));
     47     }
     48   return s;
     49 }
     50 void dfs1(int x,int pa)
     51 {int i;
     52   fa[x]=pa;
     53   size[x]=1;dep[x]=dep[pa]+1;
     54   for (i=head[x];i;i=edge[i].next)
     55     {
     56       int v=edge[i].to;
     57       if (v==pa) continue;
     58       dfs1(v,x);
     59       size[x]+=size[v];
     60       if (size[son[x]]<size[v]) son[x]=v;
     61     }
     62 }
     63 void dfs2(int x,int pa,int tp)
     64 {int i;
     65   dfn[x]=++cnt;
     66   top[x]=tp;
     67   add(cnt,a[x]);
     68   if (son[x])
     69     dfs2(son[x],x,tp);
     70   for (i=head[x];i;i=edge[i].next)
     71     {
     72       int v=edge[i].to;
     73       if (v==pa||v==son[x]) continue;
     74       dfs2(v,x,v);
     75     }
     76 }
     77 int ask(int x,int y)
     78 {
     79   int s=0;
     80   while (top[x]!=top[y])
     81     {
     82       if (dep[top[x]]<dep[top[y]]) swap(x,y);
     83       s^=query(dfn[top[x]]-1)^query(dfn[x]);
     84       x=fa[top[x]];
     85     }
     86   if (dep[x]>dep[y]) swap(x,y);
     87   s^=query(dfn[x]-1)^query(dfn[y]);
     88   return s;
     89 }
     90 int main()
     91 {int i,u,v;
     92   char s[21];
     93   cin>>n;
     94   for (i=1;i<=n;i++)
     95     {
     96       a[i]=gi();
     97     }
     98   for (i=1;i<=n-1;i++)
     99     {
    100       u=gi();v=gi();
    101       insert(u,v);insert(v,u);
    102     }
    103   dfs1(1,0);
    104   dfs2(1,0,1);
    105   cin>>m;
    106   for (i=1;i<=m;i++)
    107     {
    108       scanf("%s",s);
    109       u=gi();v=gi();
    110       if (s[0]=='Q')
    111     {
    112       if (ask(u,v)) printf("Yes
    ");
    113       else printf("No
    ");
    114     }
    115       else
    116     {
    117       add(dfn[u],a[u]);
    118       add(dfn[u],v);
    119       a[u]=v;
    120     }
    121     }
    122 }
  • 相关阅读:
    以太网的寻址
    IP地址简介
    服务器控件与Html控件属性值的解释差异
    The Live Hacking CD
    德国SNS交友/视频网站Poppen.de的技术架构分享
    Forensic Log Parsing with Microsoft's LogParser
    The Flame: Questions and Answers
    hping
    WIN7与XP网络共享与访问
    Win7无法访问NAS或Samba解决之道
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8390840.html
Copyright © 2020-2023  润新知