#417 Div2 E (树上阶梯博弈)
#417 Div2 E
题意
给出一颗苹果树,设定所有叶子节点的深度全是奇数或偶数,并且包括根在内的所有节点上都有若干个苹果。
两人进行游戏,每回合每个人可以做下列两种操作中的一种:
- 每个人可以吃掉某个叶子节点上的部分苹果。
- 将某个非叶子结点上的部分苹果移向它的孩子。
吃掉树上最后一个苹果的人获胜。
后手可以在游戏开始之前交换两个不同节点的苹果,输出交换后能使得后手胜利的交换总的方案数。
分析
其实就是阶梯博弈裸题。
分两种情况:
- 叶子节点深度为奇数,那么只需要对所有深度为奇数的节点求异或和(Nim博弈),异或和等于 0 时先手必败,无论必败方怎么操作,必胜方都可以通过适当的操作抵消掉必败方的操作。在求方案数的时候,对于异或和为 0 的情况,分别在奇数深度节点和偶数深度节点内进行交换,然后遍历奇数深度的节点,从偶数深度节点内找到值为 xor_sum^odd[i] 的节点。
- 叶子节点深度为偶数,对深度为偶数的节点求异或和,其它同理。
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 10;
const int N = 1e7 + 5;
int n;
int has[MAXN];
int dep[MAXN];
vector<int> G[MAXN];
int oddxor, evenxor;
ll even, odd;
int evenn[N], oddn[N];
vector<int> oddv, evenv;
int f;
void dfs(int pre, int x, int d) {
    dep[x] = d;
    if(d & 1) {
        odd++;
        oddv.push_back(x);
        oddn[has[x]]++;
        oddxor ^= has[x];
    } else {
        even++;
        evenv.push_back(x);
        evenn[has[x]]++;
        evenxor ^= has[x];
    }
    if(!G[x].size() && dep[x] & 1) f = 1;
    for(int i = 0; i < G[x].size(); i++) {
        int v = G[x][i];
        if(v != pre) dfs(x, v, d + 1);
    }
}
int main() {
    cin >> n;
    for(int i = 1; i <= n; i++) {
        cin >> has[i];
    }
    for(int i = 2; i <= n; i++) {
        int x;
        cin >> x;
        G[x].push_back(i);
    }
    ll ans = 0;
    dfs(0, 1, 0);
    if(f) {
        if(!oddxor) {
            ans += (even * even - even) / 2 + (odd * odd - odd) / 2;
        }
        for(int i = 0; i < oddv.size(); i++) {
            if((oddxor ^ has[oddv[i]]) < N) ans += evenn[oddxor ^ has[oddv[i]]];
        }
    } else {
        if(!evenxor) {
            ans += (even * even - even) / 2 + (odd * odd - odd) / 2;
        }
        for(int i = 0; i < evenv.size(); i++) {
            if((evenxor ^ has[evenv[i]]) < N) ans += oddn[evenxor ^ has[evenv[i]]];
        }
    }
    cout << ans << endl;
    return 0;
}
#417 Div2 E (树上阶梯博弈)的更多相关文章
- 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 ... 
- HDU 4315 Climbing the Hill (阶梯博弈转尼姆博弈)
		Climbing the Hill Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u Su ... 
- POJ1704 Georgia and Bob (阶梯博弈)
		Georgia and Bob Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u Subm ... 
- HDU 4315:Climbing the Hill(阶梯博弈)
		http://acm.hdu.edu.cn/showproblem.php?pid=4315 题意:有n个人要往坐标为0的地方移动,他们分别有一个位置a[i],其中最靠近0的第k个人是king,移动的 ... 
- HDU 5996:dingyeye loves stone(阶梯博弈)
		http://acm.hdu.edu.cn/showproblem.php?pid=5996 题意:在一棵树上进行博弈,每次只能将当前的结点的石子放到父节点上,最后不能移动的输. 思路:比赛的时候想的 ... 
- hdu 3389 Game (阶梯博弈)
		#include<stdio.h> int main() { int t,n,ans; int i,j,x; scanf("%d",&t); ;j<=t; ... 
- poj 1704 阶梯博弈
		转自http://blog.sina.com.cn/s/blog_63e4cf2f0100tq4i.html 今天在POJ做了一道博弈题..进而了解到了阶梯博弈...下面阐述一下我对于阶梯博弈的理解. ... 
- [BZOJ 1115] [POI2009] 石子游戏Kam 【阶梯博弈】
		题目链接:BZOJ - 1115 题目分析 首先看一下阶梯博弈: 阶梯博弈是指:初始有 n 堆石子,每次可以从任意的第 i 堆拿若干石子放到第 i - 1 堆.最终不能操作的人失败. 解法:将奇数位的 ... 
- codevs 1421 秋静叶&秋穣子(树上DP+博弈)
		1421 秋静叶&秋穣子 题目描述 Description 在幻想乡,秋姐妹是掌管秋天的神明,作为红叶之神的姐姐静叶和作为丰收之神的妹妹穰子.如果把红叶和果实联系在一 起,自然会想到烤红薯 ... 
随机推荐
- Centos7中查看IP地址命令ifconfig无法识别如何处理
			问题描述: 在虚拟机中已安装好Centos7系统,查看IP地址使用命令ifconfig时,提示找不到此命令,使用ip addr命令则可查询当前系统的IP地址(如图1.2): 图1 图2 解决问题步骤: ... 
- winform-windowsmediaplayer设置可视化效果之条形
			winform导入windowsmediaplayer这个COM组件,他的默认可视化效果为: 而我们需要的可视化效果为: 则我们可以通过代码更改可视化效果:(参数value设为4即可!) //设置可视 ... 
- (原)Unreal渲染相关的缓冲区 及其 自定义代码几种抓取
			@authot: 白袍小道 转载说明那啥即可. (图片和本文无关,嘿嘿,坑一下) 以下为Unreal4.18版本中对GPUBuffer部分的分析结果 (插入:比之够着,知至目的) ... 
- sql 删除重复的类型并且时间相同的项
			delete RemoteDetection WHERE REMOTEDETECTIONID IN ( select ID from ( select MIN(REMOTEDETECTIONID) I ... 
- centos 7 安装codeblocks
			CentOS7安装Code::Blocks 在CentOS7上安装Codelocks的过程. 1.安装gcc,需要c和c++两部分,默认安装下,CentOS不安装编译器的,在终端输入以下命令即可yum ... 
- shell之iptables
			这五个位置也被称为五个钩子函数(hook functions),也叫五个规则链. 1.PREROUTING (路由前) 2.INPUT (数据包流入口) 3.FORWARD (转发管卡) 4.OUTP ... 
- DAO设计模式的理解
			为了降低耦合性,提出了DAO封装数据库操作的设计模式. 它可以实现业务逻辑与数据库访问相分离.相对来说,数据库是比较稳定的,其中DAO组件依赖于数据库系统,提供数据库访问的接口. 一般的DAO的封装由 ... 
- android之SlideMenu双向滑动
			开始动手之前先来讲一下实现原理,在一个Activity的布局中需要有三部分,一个是左侧菜单的布局,一个是右侧菜单的布局,一个是内容布局.左侧菜单居屏幕左边缘对齐,右侧菜单居屏幕右边缘对齐,然后内容布局 ... 
- 【bzoj4881】[Lydsy2017年5月月赛]线段游戏  树状数组+STL-set
			题目描述 quailty和tangjz正在玩一个关于线段的游戏.在平面上有n条线段,编号依次为1到n.其中第i条线段的两端点坐标分别为(0,i)和(1,p_i),其中p_1,p_2,...,p_n构成 ... 
- msvs命令行编译lua5.3.4
			msvs命令行编译lua5.3.4 vslua.bat @echo off md bin md lib md include cd src cl /c /nologo /W3 /O2 /Ob1 /Oi ... 
