F Christmas Game

题意:

给一棵n个节点树,每个点上都有权值,两个人轮流操作,每次可以将一个点的权值给他的父亲节点,(父亲节点与当前点的深度差必须为k),当有一方不能操作时即为输掉。问依次以n个点为根的情况下,先手能否赢

题解:

博弈论
我第一反应是尼姆博弈
我们把节点相对于根的深度分为奇数和偶数
我们这里说的步数是指一个节点上的所能走的步数,因为每次走的长度是固定的(必须向上走深度为k)
如果把一些权值从一个偶数步移动到奇数步,那么对面可以重复一样的行为,这样输的一定是先手(因为后手可以模仿先手)
所以先手想赢必须走奇数步,换句话说偶数步不会对比赛结果有影响可以舍弃
奇数步是如何定义的呢?我们刚才说了和k有很大的关系,如果当前节点x的深度为dep,x的奇偶性是dep/x(向下取整)
我们现在拿到所有奇数步的结果怎么判断胜负?
经典博弈问题NIM游戏
a1⊕a2⊕…⊕an不为零时,当前玩家有一个获胜策略。
总结一下:
如果奇数步上所有值的xorsum不为零,则先手获胜获胜策略。

代码:

我一开始写的dfs直接暴力超时了

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
const int maxn=1e5+8;
vector<int>edge[maxn];
int a[maxn];
int root;
int dep[maxn];
int cnt=0;
int x=0;
int n,k;
inline void dfs(int fa,int now){dep[now]=dep[fa]+1;if((dep[now]/k)&1)x^=a[now];for(int i=0;i<edge[now].size();i++){int v=edge[now][i];if(v!=fa)dfs(now,v);}
}
//void solve(int now){
//  int x=0;
//  int y=0;
//  int i,j=2*k;
//  int last=k;
//  for(i=k;i<=n;i+=k)
//  {
//      for(j=last+1;j<=i;j++)
//      {
//          for(int k=1;k<=n;k++)
//              if(a[j]==k)
//              {
//
//              }
//      }
//      last=i;
//  }
////    for(int i=k+1;i<=cnt;y++,i++)
////    {
////        for(int j=1;j<=n;j++)
////            if(a[j]==i)
////            {
////                if(y&1)
////                {
////                    x^=a[j];
////                }
////                else
////                {
////                    continue;
////                }
////            }
////    }
//}
int main()
{//cin>>n>>k;n=read();k=read();for(int i=1;i<n;i++){int u,v;u=read();v=read();//cin>>u>>v;edge[u].push_back(v);edge[v].push_back(u);}for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){root=i;x=0;memset(dep,0,sizeof(dep));cnt=0;dep[0]=-1;dfs(0,root);if(x==0)cout<<0<<" ";else cout<<1<<" ";}return 0;
}

然后我在想简化的话就不能对每个点跑一次dfs,跑一次+换根是不是可以?然后我看了看别人的代码。。。没看啥意思

#include <cstdio>
#include <vector>
using namespace std;
vector<int> mp[100005];
int n,k;
int a[100005];
int dp[100005][45];
int ans[100005][45];
//
void dfs(int x,int fa)
{dp[x][0]=a[x];for(int i=0;i<mp[x].size();i++)if(mp[x][i]!=fa){dfs(mp[x][i],x);for(int j=0;j<2*k;j++)//mp[x][i]是x的第i个子节点 dp[x][j]^=dp[mp[x][i]][(j+2*k-1)%(2*k)];}
}
void dfss(int x,int fa)
{for(int i=0;i<mp[x].size();i++)if(mp[x][i]!=fa){for(int j=0;j<2*k;j++){//mp[x][i]是x的第i个子节点 ans[mp[x][i]][j]=(ans[x][(j+2*k-1)%(2*k)] ^ dp[mp[x][i]][(j+2*k-2)%(2*k)] ^ dp[mp[x][i]][j]);} dfss(mp[x][i],x);}
}
int main()
{int u,v,now;scanf("%d%d",&n,&k);for(int i=0;i<n-1;i++){scanf("%d%d",&u,&v);mp[u].push_back(v);mp[v].push_back(u);}for(int i=1;i<=n;i++)scanf("%d",&a[i]);dfs(1,0);for(int i=0;i<2*k;i++)ans[1][i]=dp[1][i];dfss(1,0);for(int i=1;i<=n;i++){now=0;for(int j=k;j<2*k;j++)now^=ans[i][j];if(now)now=1;if(i!=n)printf("%d ",now);else printf("%d\n",now);}return 0;
}

F Christmas Game相关推荐

  1. 【AtCoder】ARC088

    C - Multiple Gift 题解 首项是X,每次乘个2,暴力统计 代码 #include <bits/stdc++.h> #define fi first #define se s ...

  2. Jozky 刷题目录

    文章目录 本目录参考OI-Wiki 还未解决专区 算法基础 枚举 模拟 递归&分治 贪心 排序 前缀和&差分 二分 倍增 构造 搜索 DFS && BFS 双向搜索 启 ...

  3. CodeCraft-21 and Codeforces Round #711 (Div. 2)

    CodeCraft-21 and Codeforces Round #711 (Div. 2) 题号 题目 考点 A GCD Sum 签到,模拟 B Box Fitting 贪心 C Planar R ...

  4. Atcoder 乱做

    最近感觉自己思维僵化,啥都不会做了-- ARC103 F Distance Sums 题意 给定第 \(i\) 个点到所有点的距离和 \(D_i\) ,要求构造一棵合法的树.满足第 \(i\) 个点到 ...

  5. 【POJ - 3160】Father Christmas flymouse(Tarjan缩点,DAG最长路)

    题干: After retirement as contestant from WHU ACM Team, flymouse volunteered to do the odds and ends s ...

  6. 【Christmas Game】【CodeCraft-21 and Codeforces Round #711 (Div. 2)】【Nim-博弈】【树形DP】【拆分树】

    CodeCraft-21 and Codeforces Round #711 (Div. 2) Christmas Game Nim-博弈 树形DP 拆分树 牛客链接 https://ac.nowco ...

  7. python %f 怎样指定小数点的位数

    %f 格式化浮点数字,可指定小数点后的精度 看下面的 pi = 3.14 print("当前的p= %f" % pi) 打印结果如下 想保留小数点后多少位数只需要在f 前面添加相应 ...

  8. [codeforces]Round #538 (Div. 2) F. Please, another Queries on Array?

    题解:    $$  ans=F\left ( \prod _{i=l}^{r}a_i \right ) $$ $$ =(p_i-1){p_i}^{k_i-1}*.....*(p_j-1){p_j}^ ...

  9. Ubuntu apt-get install、apt-get -f install、apt-get --purge remove、apt-get update、apt-get upgrade、

    1. 常用命令列表 命令 描述 apt-cache search package 搜索软件包 apt-cache show package 获取包的相关信息,如说明.大小.版本等 sudo apt-g ...

最新文章

  1. Centos7创建用户并授予sudo权限
  2. app应用内嵌h5页面怎么直接打开safari_localstroage过多存储满的情况下应该怎么办?...
  3. Java性能调优调查结果(第四部分)
  4. sqlyog设置自动补全_Visual Studio Code 最好的功能、插件和设置
  5. 年终将至,如何轻松搞定工作汇报PPT?
  6. Netty工作笔记0002---Netty的应用场景
  7. jq js json 转字符串_js-jquery-对象与JSON字符串互相转换
  8. 格雷码与二进制码的转换
  9. BI_DBA_安装(3):安装informatic
  10. Ubuntu 20.04 禁用笔记本电脑自带键盘
  11. Thinkpad E430c安装Ubuntu14.04第三方驱动的选择
  12. LTE相关协议2——下行峰值速率计算
  13. Android Studio 全局搜索快捷键
  14. Allegro自动对齐工具
  15. 周志明虚拟机最新版,大厂面试必备宝典
  16. 现在有的年轻人想法有点畸形
  17. A002-186-2610
  18. 云计算机开始用使用了没有,有MacBook可以用的云电脑吗
  19. Promethus===》普罗米修斯简介、时序数据库、监控系统的基本使用
  20. 水溶性丙烯酸树脂增稠剂,还是有点小疑惑?

热门文章

  1. 史上最神奇的公式,竟然藏着这么多秘密!
  2. 辍学程序员改变世界,这位长得像马云的90后要击败Facebook的扎克伯格了…
  3. 21张GIF动图让你秒懂数学原理
  4. 快速掌握MATLAB应用,从这一步开始
  5. Linux系统管理员的Bash指南,11条Bash实践经验!
  6. 看国外女神级程序员,直播写代码一年的感悟
  7. 服务器文件每天备份重新命名,定时备份服务器文件至本地电脑
  8. ensp查看历史配置命令_华为eNSP常用命令
  9. 早教机器人刷固件_机器人线刷包_机器人刷机包_机器人固件包_机器人救砖包 - 线刷宝ROM中心...
  10. 钣金缺口lisp_UG用钣金模块的放样创建天圆地方,还能学钣金展开,必看