#417 Div2 E

题意

给出一颗苹果树,设定所有叶子节点的深度全是奇数或偶数,并且包括根在内的所有节点上都有若干个苹果。

两人进行游戏,每回合每个人可以做下列两种操作中的一种:

  • 每个人可以吃掉某个叶子节点上的部分苹果。
  • 将某个非叶子结点上的部分苹果移向它的孩子。

吃掉树上最后一个苹果的人获胜。

后手可以在游戏开始之前交换两个不同节点的苹果,输出交换后能使得后手胜利的交换总的方案数。

分析

其实就是阶梯博弈裸题。

分两种情况:

  1. 叶子节点深度为奇数,那么只需要对所有深度为奇数的节点求异或和(Nim博弈),异或和等于 0 时先手必败,无论必败方怎么操作,必胜方都可以通过适当的操作抵消掉必败方的操作。在求方案数的时候,对于异或和为 0 的情况,分别在奇数深度节点和偶数深度节点内进行交换,然后遍历奇数深度的节点,从偶数深度节点内找到值为 xor_sum^odd[i] 的节点。
  2. 叶子节点深度为偶数,对深度为偶数的节点求异或和,其它同理。

code

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int MAXN = 1e5 + 10;
  5. const int N = 1e7 + 5;
  6. int n;
  7. int has[MAXN];
  8. int dep[MAXN];
  9. vector<int> G[MAXN];
  10. int oddxor, evenxor;
  11. ll even, odd;
  12. int evenn[N], oddn[N];
  13. vector<int> oddv, evenv;
  14. int f;
  15. void dfs(int pre, int x, int d) {
  16. dep[x] = d;
  17. if(d & 1) {
  18. odd++;
  19. oddv.push_back(x);
  20. oddn[has[x]]++;
  21. oddxor ^= has[x];
  22. } else {
  23. even++;
  24. evenv.push_back(x);
  25. evenn[has[x]]++;
  26. evenxor ^= has[x];
  27. }
  28. if(!G[x].size() && dep[x] & 1) f = 1;
  29. for(int i = 0; i < G[x].size(); i++) {
  30. int v = G[x][i];
  31. if(v != pre) dfs(x, v, d + 1);
  32. }
  33. }
  34. int main() {
  35. cin >> n;
  36. for(int i = 1; i <= n; i++) {
  37. cin >> has[i];
  38. }
  39. for(int i = 2; i <= n; i++) {
  40. int x;
  41. cin >> x;
  42. G[x].push_back(i);
  43. }
  44. ll ans = 0;
  45. dfs(0, 1, 0);
  46. if(f) {
  47. if(!oddxor) {
  48. ans += (even * even - even) / 2 + (odd * odd - odd) / 2;
  49. }
  50. for(int i = 0; i < oddv.size(); i++) {
  51. if((oddxor ^ has[oddv[i]]) < N) ans += evenn[oddxor ^ has[oddv[i]]];
  52. }
  53. } else {
  54. if(!evenxor) {
  55. ans += (even * even - even) / 2 + (odd * odd - odd) / 2;
  56. }
  57. for(int i = 0; i < evenv.size(); i++) {
  58. if((evenxor ^ has[evenv[i]]) < N) ans += oddn[evenxor ^ has[evenv[i]]];
  59. }
  60. }
  61. cout << ans << endl;
  62. return 0;
  63. }

#417 Div2 E (树上阶梯博弈)的更多相关文章

  1. Codeforces Round #417 (Div. 2)A B C E 模拟 枚举 二分 阶梯博弈

    A. Sagheer and Crossroads time limit per test 1 second memory limit per test 256 megabytes input sta ...

  2. HDU 4315 Climbing the Hill (阶梯博弈转尼姆博弈)

    Climbing the Hill Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u Su ...

  3. POJ1704 Georgia and Bob (阶梯博弈)

    Georgia and Bob Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u Subm ...

  4. HDU 4315:Climbing the Hill(阶梯博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=4315 题意:有n个人要往坐标为0的地方移动,他们分别有一个位置a[i],其中最靠近0的第k个人是king,移动的 ...

  5. HDU 5996:dingyeye loves stone(阶梯博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=5996 题意:在一棵树上进行博弈,每次只能将当前的结点的石子放到父节点上,最后不能移动的输. 思路:比赛的时候想的 ...

  6. hdu 3389 Game (阶梯博弈)

    #include<stdio.h> int main() { int t,n,ans; int i,j,x; scanf("%d",&t); ;j<=t; ...

  7. poj 1704 阶梯博弈

    转自http://blog.sina.com.cn/s/blog_63e4cf2f0100tq4i.html 今天在POJ做了一道博弈题..进而了解到了阶梯博弈...下面阐述一下我对于阶梯博弈的理解. ...

  8. [BZOJ 1115] [POI2009] 石子游戏Kam 【阶梯博弈】

    题目链接:BZOJ - 1115 题目分析 首先看一下阶梯博弈: 阶梯博弈是指:初始有 n 堆石子,每次可以从任意的第 i 堆拿若干石子放到第 i - 1 堆.最终不能操作的人失败. 解法:将奇数位的 ...

  9. codevs 1421 秋静叶&秋穣子(树上DP+博弈)

    1421 秋静叶&秋穣子   题目描述 Description 在幻想乡,秋姐妹是掌管秋天的神明,作为红叶之神的姐姐静叶和作为丰收之神的妹妹穰子.如果把红叶和果实联系在一 起,自然会想到烤红薯 ...

随机推荐

  1. 嵌入式(Embedded System)笔记 —— Cortex-M3 Introduction and Basics(下)

    随着课内的学习,我想把每节课所学记录下来,以作查阅.以饲读者.由于我所上的是英文班课程,因此我将把关键术语的英文给出,甚至有些内容直接使用英文. 本次所介绍内容仍是关于Cortex-M3的基础内容,相 ...

  2. pytest单元测试框架

    一.安装方式 1.安装命令:pip install pytest 2.html安装插件:pip install pytest -html 二.pytest执行指定测试用例 1.思想:通过对测试用例进行 ...

  3. 源码分析(一) HashMap 源码分析|JDK8

    HashMap是一个普遍应用于各大JAVA平台的最最最常用的数据结构.<K,V>的存储形式使HashMap备受广大java程序员的喜欢.JDK8中HashMap发生了很大的变化,例如:之前 ...

  4. virt-install command

    安装 virt-install --connect qemu:///system \ --virt-type=kvm \ --name windows2008 --ram --vcpus --arch ...

  5. C++ 虚函数的内存分配

    1.无继承的普通类:   在有虚函数的情况下类会为其增加一个隐藏的成员,虚函数表指针,指向一个虚函数表,虚函数表里面就是类的各个虚函数的地址了.那么,虚函数表指针是以什么模型加入到类里面的,虚函数表里 ...

  6. 使用pdb模块调试Python

    在Python中,我们需要debug时,有三种方式: 加log语句.最简单的方式是添加print()语句来输出我们想要获知的状态或者变量,好处是简单容易操作,坏处是debug完了之后,还需要将prin ...

  7. java中unmodifiableList方法的应用场景

    java对象中primitive类型变量可以通过不提供set方法保证不被修改,但对象的List成员在提供get方法后,就可以随意add.remove改变其结构,这不是希望的结果.网上看了下,发现Col ...

  8. 关于spark RDD trans action算子、lineage、宽窄依赖详解

    这篇文章想从spark当初设计时为何提出RDD概念,相对于hadoop,RDD真的能给spark带来何等优势.之前本想开篇是想总体介绍spark,以及环境搭建过程,但个人感觉RDD更为重要 铺垫 在h ...

  9. POJ 1149 PIGS | 最大流问题

    参考了这个PDF 第一道网络流啊!感动 #include<cstdio> #include<algorithm> #include<cstring> #includ ...

  10. Codeforces 938.B Run For Your Prize

    B. Run For Your Prize time limit per test 1 second memory limit per test 256 megabytes input standar ...