zoukankan      html  css  js  c++  java
  • #阶梯NIM,树形dp#CF1498F Christmas Game

    题目

    Alice 和 Bob 在一棵 (n) 个点的树上玩游戏,第 (i) 个节点上有 (a_i) 个石子,

    每轮可以选择一个深度至少为 (k) 的节点并移动任意多石子到其 (k) 级祖先处,对每个结点询问如果将其作为根谁会赢。


    分析

    (dp[x][d])表示以 (x) 为根的子树离(x)的距离(mod 2k)(d) 的SG值

    由于先手移动偶数层后手可以用同样的方式移上去所以只需要考虑奇数层的SG值,

    直接二次扫描换根即可


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=100011; struct node{int y,next;}e[N<<1];
    int dp[N][40],n,m,ans[N],a[N],et=1,as[N],f[40];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans; 
    }
    inline void dfs1(int x,int fa){
    	dp[x][0]=a[x];
    	for (rr int i=as[x];i;i=e[i].next)
    	if (e[i].y!=fa){
    		dfs1(e[i].y,x);
    		for (rr int j=0;j<m;++j)
    			dp[x][(j+1)%m]^=dp[e[i].y][j];
    	}
    }
    inline void dfs2(int x,int fa){
    	if (fa){
    		for (rr int j=0;j<m;++j) f[(j+1)%m]=dp[fa][(j+1)%m]^dp[x][j];	
    	    for (rr int j=0;j<m;++j) dp[x][(j+1)%m]^=f[j];
    	}
    	for (rr int i=as[x];i;i=e[i].next)
    	    if (e[i].y!=fa) dfs2(e[i].y,x);
    }
    signed main(){
    	n=iut(),m=iut()<<1;
    	for (rr int i=1;i<n;++i){
    		rr int x=iut(),y=iut();
    		e[++et]=(node){y,as[x]},as[x]=et;
    		e[++et]=(node){x,as[y]},as[y]=et;
    	}
    	for (rr int i=1;i<=n;++i) a[i]=iut();
    	dfs1(1,0),dfs2(1,0);
    	for (rr int i=1;i<=n;++i){
    		for (rr int j=m/2;j<m;++j) ans[i]^=dp[i][j];
    		putchar((ans[i]>0)+48),putchar(32);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Beta冲刺<10/10>
    Beta冲刺<1/10>
    多语言工作者--凡事预则立
    Beta阶段代码与规范
    多语言工作者の十日冲刺<9/10>
    团队进行Alpha冲刺--项目测试
    团队进行Alpha冲刺--冲刺总结
    Alpha总结展望——前事不忘后事之师
    Beta冲刺随笔——Day_Five
    Beta冲刺随笔——Day_Two
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/15179651.html
Copyright © 2011-2022 走看看