zoukankan      html  css  js  c++  java
  • [atAGC017D]Game on Tree

    将其1为根建树,操作显然即去掉一棵子树(非本身)

    考虑sg函数,定义$sg(T)$为有根树$T$的sg值,则有以下结论——

    结论:令$T'$为$T$的根节点新增一个父亲得到的树,则$sg(T')=sg(T)+1$

    假设去掉$T$任意一棵子树(非本身)后会得到$T_{1},T_{2},...,T_{k}$,$T'_{i}$为$T_{i}$的根节点新增一个父亲得到的树,那么$T'$去掉任意一棵子树(非本身)后即会得到$T'_{1},T'_{2},...,T'_{k}$和"一个节点"的树

    显然"一个节点"的树的$sg$值为0,因此$sg(T')=mex(\{sg(T'_{i}),0\})$

    考虑归纳,并代入$sg(T'_{i})=sg(T_{i})+1$,不难得到$sg(T')=sg(T)+1$,即得证

    进一步的,考虑$T$根节点儿子的子树依次为$T_{1},T_{2},...,T_{k}$,显然对$T_{i}$再加上$T$根节点即是一个独立的问题,结合sg函数的性质和结论,也即$sg(T)=\bigoplus_{i=1}^{k}(sg(T_{i})+1)$,再树形dp即可

    时间复杂度为$o(n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 vector<int>v[N];
     5 int n,x,y,sg[N];
     6 void dfs(int k,int fa){
     7     for(int i=0;i<v[k].size();i++)
     8         if (v[k][i]!=fa){
     9             dfs(v[k][i],k);
    10             sg[k]^=sg[v[k][i]]+1;
    11         }
    12 }
    13 int main(){
    14     scanf("%d",&n);
    15     for(int i=1;i<n;i++){
    16         scanf("%d%d",&x,&y);
    17         v[x].push_back(y);
    18         v[y].push_back(x);
    19     }
    20     dfs(1,0);
    21     if (sg[1])printf("Alice\n");
    22     else printf("Bob\n");
    23     return 0;
    24 }
    View Code
  • 相关阅读:
    2020蓝桥杯模拟赛(一)
    自己整理的瀑布流+滚动加载图片的例子
    .NET如何发送格式化的文本内容
    Bootstrap学习笔记(3)--表格表单图片
    BootStap学习笔记(2)
    BootStap学习笔记(1)
    Oracle性能优化
    Maven+spring+springMVC+mybatis+Junit+Log4j配置个人总结
    C#指针和寻址运算
    Linq to XML
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15633264.html
Copyright © 2011-2022 走看看