首页 > 代码库 > Codeforces 812E Sagheer and Apple Tree ——(阶梯博弈)

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 }

 

Codeforces 812E Sagheer and Apple Tree ——(阶梯博弈)