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 }
时间: 2024-08-05 23:40:38

Codeforces 812E Sagheer and Apple Tree ——(阶梯博弈)的相关文章

Codeforces 812E Sagheer and Apple Tree

大致题意: 给你一颗树,这个树有下列特征:每个节点上有若干个苹果,且从根节点到任意叶子节点的路径长度奇偶性相同. 甲和乙玩(闲)游(得)戏(慌). 游戏过程中,甲乙轮流将任意一个节点的若干个苹果移向它的一个叶子节点,若没有叶子节点,那么这些苹果就消失了(被吃掉了). 若一个玩家没法操作,那么算他输. 游戏由甲开始,而乙可以先选择将两个节点上的苹果数交换一下.问乙有多少种交换方式,使得最后乙获胜. Nim游戏: 如果懂Nim游戏的话,就不要看了\(^o^)/~你肯定会这道题了. 懂Nim游戏的定义

Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree(树上Nim)

题目链接:Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree 题意: 给你一棵树,每个节点有a[i]个苹果,有两个人要在这个树上玩游戏. 两个人轮流操作,谁不能操作谁就输了. 这个树有一个特性:叶子到根的距离的奇偶性相同. 每次操作可以选一个节点i,和一个数x,x小于当前节点i的苹果数. 对于节点i,如果是叶子节点,就将这x个苹果吃掉. 如果是非叶子节点,就将这x个苹果移向节点i的任意儿子节点. 现在第二个操作的人要交换两个节点的苹果

(博弈\sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree

Sagheer is playing a game with his best friend Soliman. He brought a tree with n nodes numbered from 1 to n and rooted at node 1. The i-th node has ai apples. This tree has a special property: the lengths of all paths from the root to any leaf have t

codeforces 812 E. Sagheer and Apple Tree(树+尼姆博弈)

题目链接:http://codeforces.com/contest/812/problem/E 题意:有一颗苹果树,这个苹果树所有叶子节点的深度要不全是奇数,要不全是偶数,并且包括根在内的所有节点上都有若干个苹果,现有两个,每个人可以吃掉某个叶子节点上的部分苹果(不能不吃),或者将某个非叶子结点上的部分苹果移向它的孩子(当然也不能不移),吃掉树上最后一个苹果的人获胜.后手可以在游戏开始之前交换任意两个不同的节点的苹果,输出交换后能使得后手胜利的交换总数. 题解:这题挺友善的所有叶子结点的深度奇

cf202-div 1-B - Apple Tree:搜索,数论,树的遍历

http://codeforces.com/contest/348/problem/B B. Apple Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given a rooted tree with n vertices. In each leaf vertex there's a single

POJ3321 Apple Tree

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26989   Accepted: 8004 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been

阶梯博弈

由于bestcoder的一道题,去学习了一下阶梯博弈. 大概理解如下:有n层的阶梯,每一层上都有若干的石子,可以将任何一层的石子,拿出至少一个,放到它的上一层上去,最后一个不能进行操作的人输. 那么,必胜策略是怎么样的呢?首先,我们令最高层为0层,依次为1,2,...,n-1层.那么,结论就是奇数层的石子做nim即可. 为什么这样是可行的呢?解释如下:对于偶数层,2,4,6...等,从这里移动石子,下一个人可以模仿着这动作将这么多的石子移动到下一层,例如,对方移动x个石子从2到1,那么我模仿他将

timus 1018. Binary Apple Tree

1018. Binary Apple Tree Time limit: 1.0 secondMemory limit: 64 MB Let's imagine how apple tree looks in binary computer world. You're right, it looks just like a binary tree, i.e. any biparous branch splits up to exactly two new branches. We will enu

poj 2486 a apple tree

题意:n节点的树,从1开始走,总共v步,每个点都有一个价值,求可以获得的最大价值 分析:这个显然可以走回来,那么就加一维表示是否走回祖先 dp[u][i][j]表示从u为根节点的子树,往下走i步,j=0表示不走回来,j=1表示走回来 那么可以得到状态转移方程,不走回来的可能会影响走回来的,如果先算不会来的,那么一个节点在不走回来算一次 在走回来又算一次,所以先算走回来的就可以避免 dp[u][i][0]=max(dp[u][i][0],dp[u][i-j][1]+dp[v][j-1][0]);