zoukankan      html  css  js  c++  java
  • Codeforces 812E Sagheer and Apple Tree ——(阶梯博弈)

      之前在bc上做过一道类似的阶梯博弈的题目,那题是移动到根,这题是移动到叶子。换汤不换药,只要和终态不同奇偶的那些位置做nim即可。因此这题给出了一个条件:所有叶子深度的奇偶性相同。同时需要注意的是,上次bc中,根节点是不能移动的,因此根节点是终态节点,而这里叶子上面还可以进行操作(可以吃掉),那么就相当于叶子节点都还可以继续向下移动,因此他们不是终态节点,也就是说这题只要和叶子节点同奇偶的做nim即可。

      因此,如果nim和已经是0,已经可以满足先手必输了,而题目说了必须要交换,那么只要让奇偶性相同的节点做交换即可,统计一下奇偶节点的个数再C(cnt, 2)就做完了;否则,后手必须要把和叶子节点不同奇偶的换过去来使得nim和为0,利用异或的性质以及map就可以做出来了。具体见代码:

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 #include <map>
     5 #include <vector>
     6 #include <iostream>
     7 using namespace std;
     8 const int N = 1e5 + 5;
     9 typedef long long ll;
    10 
    11 int a[N];
    12 vector<int> G[N];
    13 int n;
    14 int ji = -1;
    15 void dfs(int u,int fa,int deep)
    16 {
    17     if(ji != -1) return ;
    18     int flag = 0;
    19     for(int i=0;i<G[u].size();i++)
    20     {
    21         int v = G[u][i];
    22         if(v != fa)
    23         {
    24             flag = 1;
    25             dfs(v, u, deep + 1);
    26         }
    27     }
    28     if(flag == 0)
    29     {
    30         ji = deep % 2;
    31     }
    32 }
    33 vector<int> yes, no;
    34 void dfs2(int u,int fa,int deep)
    35 {
    36     if(deep % 2 == ji) yes.push_back(a[u]);
    37     else no.push_back(a[u]);
    38     for(int i=0;i<G[u].size();i++)
    39     {
    40         int v = G[u][i];
    41         if(v != fa)
    42         {
    43             dfs2(v, u, deep + 1);
    44         }
    45     }
    46 }
    47 ll comb(int x) {if(x < 2) return 0; return (ll)x*(x-1) / 2;}
    48 
    49 int main()
    50 {
    51     scanf("%d",&n);
    52     for(int i=1;i<=n;i++) scanf("%d",a+i);
    53     for(int i=2;i<=n;i++)
    54     {
    55         int v;
    56         scanf("%d",&v);
    57         G[i].push_back(v);
    58         G[v].push_back(i);
    59     }
    60     dfs(1, -1, 1);
    61     dfs2(1, -1, 1);
    62     int temp = 0;
    63     for(int i=0;i<yes.size();i++) temp ^= yes[i];
    64     if(temp == 0)
    65     {
    66         ll ans = comb(yes.size()) + comb(no.size());
    67         map<int,int> inyes;
    68         for(int i=0;i<yes.size();i++) inyes[yes[i]]++;
    69         for(int i=0;i<no.size();i++) ans += (ll)inyes[no[i]];
    70         cout << ans << endl;
    71     }
    72     else
    73     {
    74         ll ans = 0;
    75         map<int,int> inno;
    76         for(int i=0;i<no.size();i++) inno[no[i]]++;
    77         for(int i=0;i<yes.size();i++)
    78         {
    79             ll t2 = temp ^ (yes[i]);
    80             ans += inno[t2];
    81         }
    82         cout << ans << endl;
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    pku 1061 青蛙的约会 扩展欧几里得
    莫比乌斯反演
    51Nod 1240 莫比乌斯函数
    51Nod 1284 2 3 5 7的倍数 容斥原理
    51Nod 1110 距离之和最小 V3 中位数 思维
    51Nod 1108 距离之和最小 V2 1096 距离之和最小 中位数性质
    HDU 2686 Matrix 多线程dp
    51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化
    HDU 1317XYZZY spfa+判断正环+链式前向星(感觉不对,但能A)
    设计模式(4)---单例模式
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6938732.html
Copyright © 2011-2022 走看看