zoukankan      html  css  js  c++  java
  • 牛客练习赛63 牛牛的树行棋 差分 树上博弈 sg函数

    LINK:牛牛的树行棋

    本来是不打算写题解的。

    不过具体思考 还是有一段时间的。

    看完题 一直想转换到阶梯NIM的模型上 转换失败。

    考虑SG函数. 容易发现 SG函数(sg_x=max{sg_{tn}+1}land tnin sonx)

    这样就可以判断整个局面的获胜与否 然后就是问所有的第一步可以获胜的方法。

    那肯定是给对方一个必败的局面即可 考虑对每个点找答案 那么就是每个点子树内 不包括本身 (ans)^(sg_x)的出现次数。

    dsu on tree确实可以做 不过显得没有必要 线段树合并确实可以做 不过过于麻烦 由于只是单点差值 可以栈内外差分即可。

    const int MAXN=500010;
    int n,ans,len;ll cnt;
    int f[MAXN],c[MAXN];
    int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
    inline void add(int x,int y)
    {
    	ver[++len]=y;nex[len]=lin[x];lin[x]=len;
    	ver[++len]=x;nex[len]=lin[y];lin[y]=len;
    }
    inline void dfs(int x,int fa)
    {
    	go(x)
    	{
    		if(tn!=fa)
    		{
    			dfs(tn,x);
    			f[x]=max(f[x],f[tn]+1);
    		}
    	}
    }
    inline void dp(int x,int fa)
    {
    	int need=ans^f[x];
    	int ww=need<=n?c[need]:0;
    	go(x)
    	{
    		if(tn!=fa)
    		{
    			dp(tn,x);
    		}
    	}
    	cnt+=(need<=n?c[need]:0)-ww;
    	++c[f[x]];
    }
    int main()
    {
    	//freopen("1.in","r",stdin);
    	get(n);
    	rep(2,n,i)add(read(),read());
    	dfs(1,0);
    	rep(1,n,i)ans=ans^f[i];
    	if(!ans){puts("NO");return 0;}
    	else
    	{
    		puts("YES");
    		dp(1,0);
    		putl(cnt);
    	}
    	return 0;
    }
    
  • 相关阅读:
    hdu 4521 小明系列问题——小明序列(线段树 or DP)
    hdu 1115 Lifting the Stone
    hdu 5476 Explore Track of Point(2015上海网络赛)
    Codeforces 527C Glass Carving
    hdu 4414 Finding crosses
    LA 5135 Mining Your Own Business
    uva 11324 The Largest Clique
    hdu 4288 Coder
    PowerShell随笔3 ---别名
    PowerShell随笔2---初始命令
  • 原文地址:https://www.cnblogs.com/chdy/p/12859875.html
Copyright © 2011-2022 走看看