zoukankan      html  css  js  c++  java
  • Codeforces 812E(Nim变形)

    题意:一棵树(1为根,所有叶子节点深度同奇偶),每个节点上有一些苹果。现有两种操作:1.吃掉叶子节点上的苹果;2.将非叶子节点上的苹果送给儿子节点。两人轮流操作,无法操作的人输,现在后手玩家可以任意交换两个节点的苹果数,问有多少种交换方法使得后手胜利(必须交换)。

    题解:将所有节点分为两类,深度与叶子节点同奇偶(蓝)、深度与叶子节点奇偶不同(红)。有结论:当所有蓝色节点异或和为 0 时,后手必胜。因此需要寻找有多少种交换方法可以使得蓝色节点异或和为0。

    证明:可以将所有的蓝色节点看作Nim游戏中的石堆,现在的操作可以放入(将红色节点的苹果送给蓝色儿子)也可以拿出(吃掉蓝色叶子结点的苹果 or 将蓝色节点的苹果送给红色儿子)。因此结论与Nim相同:蓝色节点异或和为 0 时,后手必胜。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int n,s,p;
     5 int a[100005];
     6 int in[100005];
     7 int vis[100005];
     8 vector<int> v[2];
     9 map<int,int> num[2];
    10 vector<int> g[100005];
    11 int dfs(int u,int deep){
    12     vis[u]=(deep%2);
    13     v[deep%2].push_back(a[u]);
    14     num[deep%2][a[u]]++;
    15     for(int i=0;i<g[u].size();i++){
    16         dfs(g[u][i],deep+1);
    17     }
    18 }
    19 int main(){
    20     s=0;
    21     scanf("%d",&n);
    22     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    23     for(int i=2;i<=n;i++){
    24         scanf("%d",&p);
    25         g[p].push_back(i);
    26         in[p]++;
    27     }
    28     dfs(1,0);
    29     int p=-1;
    30     for(int i=1;i<=n;i++){
    31         if(in[i]==0){
    32             p=vis[i];
    33             break;
    34         }
    35     }
    36     for(int i=0;i<v[p].size();i++) s^=v[p][i];
    37     LL ans=0;
    38     if(s==0){
    39         LL l1=v[0].size(),l2=v[1].size();
    40         ans+=l1*(l1-1)/2+l2*(l2-1)/2;
    41         for(int i=0;i<v[p].size();i++){
    42             int tmp=v[p][i];
    43             ans+=(LL)num[p][tmp]*num[1-p][tmp];
    44             num[p][tmp]=num[1-p][tmp]=0;
    45         }
    46     }
    47     else{
    48         for(int i=0;i<v[p].size();i++){
    49             int tmp=s^v[p][i];
    50             ans+=(LL)num[p][v[p][i]]*num[1-p][tmp];
    51             num[p][v[p][i]]=num[1-p][tmp]=0;
    52         }
    53     }
    54     printf("%lld
    ",ans);
    55 
    56     return 0;
    57 }
    Psong
  • 相关阅读:
    2016-10-17: source insight插件
    Reactor模式通俗解释
    2016-09-19: linux后台运行
    2016-08-16: 检测函数是否存在的C++模板
    2016-08-16: copy-and-swap
    2016-08-15:从YUV420P中提取指定大小区域
    2016-08-15: C++ traits
    2016-08-05:samba服务器配置
    LINQ 根据指定属性名称对序列进行排序
    Resharper
  • 原文地址:https://www.cnblogs.com/N-Psong/p/6932672.html
Copyright © 2011-2022 走看看