zoukankan      html  css  js  c++  java
  • 联考20200729 T3 树上的鼠


    分析:
    首先我们从博弈入手,看看什么情况先手必胜
    先考虑一条链的情况,假设链长为偶数,即存在中点,先手就可以抢占中点,后手无论怎么走,先手都可以走到其关于中点的对称点上
    最后后手无法操作,先手必胜
    当链长为奇数时,先手两个中点随便抢一个就可以胜利
    换在树上,求出直径中点,非直径上的点可以转化为直径上的,效果等价
    那么先手必败当且仅当起点为连通块直径的唯一中点
    转化一下问题,即一个连通块使得1不是直径唯一中点,即1的儿子的最深深度仅有一个
    考虑DP,\(f_{u,i}\)表示\(u\)为根,深度至多为\(i\)的连通块方案数
    这个暴力\(O(n^2)\)DP,发现只与最深深度有关,直接长链剖分优化就好了
    统计答案时强行钦定某个儿子最深深度为\(D\),其余的不超过\(D\)就好了,维护一个前缀和
    复杂度\(O(n)\)

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    
    #define maxn 2000005 
    #define MOD 998244353
    
    using namespace std;
    
    inline long long getint()
    {
    	long long num=0,flag=1;char c;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
    	return num*flag;
    }
    
    int n;
    vector<int>G[maxn];
    int cur,pos[maxn],son[maxn],dpt[maxn],mxd[maxn];
    long long f[maxn],g[maxn],h[maxn],sum[maxn],pd[maxn];
    int tmp[maxn];
    
    inline void dfs1(int u,int fa)
    {
    	dpt[u]=dpt[fa]+1,mxd[u]=dpt[u],g[u]=1;
    	for(int i=0;i<G[u].size();i++)if(G[u][i]!=fa)
    	{
    		dfs1(G[u][i],u),mxd[u]=max(mxd[u],mxd[G[u][i]]);
    		if(mxd[G[u][i]]>mxd[son[u]])son[u]=G[u][i];
    		g[u]=g[u]*(g[G[u][i]]+1)%MOD;
    	}
    }
    inline void dfs2(int u,int fa)
    {
    	pos[u]=++cur;if(son[u])dfs2(son[u],u);
    	for(int i=0;i<G[u].size();i++)if(G[u][i]!=fa&&G[u][i]!=son[u])dfs2(G[u][i],u);
    }
    
    inline void down(int u,int lim)
    {
    	if(h[u]!=1)
    	{
    		f[u]=f[u]*h[u]%MOD;
    		if(u<lim)h[u+1]=h[u+1]*h[u]%MOD;
    		h[u]=1;
    	}
    }
    
    inline void solve(int u,int p)
    {
    	f[pos[u]]=h[pos[u]]=sum[pos[u]]=1;
    	if(son[u])solve(son[u],u);
    	for(int i=0;i<G[u].size();i++)if(G[u][i]!=p&&G[u][i]!=son[u])
    	{
    		int v=G[u][i];solve(v,u);
    		for(int j=0;j<=mxd[v]-dpt[v];j++)
    		{
    			int k=j+1;
    			down(pos[v]+j,pos[v]+mxd[v]-dpt[v]),sum[pos[v]+j]=((j>0)*sum[pos[v]+j-1]+f[pos[v]+j])%MOD;
    			if(u==1)continue;
    			down(pos[u]+k,pos[u]+mxd[u]-dpt[u]),sum[pos[u]+k]=(sum[pos[u]+k-1]+f[pos[u]+k])%MOD;
    			f[pos[u]+k]=f[pos[u]+k]*((j>0)*sum[pos[v]+j-1]+1)%MOD+f[pos[v]+j]*sum[pos[u]+k-1]%MOD+f[pos[u]+k]*f[pos[v]+j]%MOD;
    			f[pos[u]+k]%=MOD;
    		}
    		if(u==1)continue;
    		if(mxd[v]<mxd[u])(h[pos[u]+mxd[v]-dpt[u]+1]*=(sum[pos[v]+mxd[v]-dpt[v]]+1))%=MOD;
    	}
    }
    
    int main()
    {
    	n=getint();
    	for(int i=1;i<n;i++)
    	{
    		int u=getint(),v=getint();
    		G[u].push_back(v),G[v].push_back(u);
    	}
    	dfs1(1,0),dfs2(1,0);
    	solve(1,0);
    	for(int i=2;i<=mxd[1];i++)down(i,mxd[1]),sum[i]=(i>2)*sum[i-1]+f[i];
    	long long ans=1;
    	for(int i=0;i<=n;i++)pd[i]=1,h[i]=1;
    	for(int i=0;i<G[1].size();i++)
    	{
    		int u=G[1][i];
    		for(int j=2;j<=mxd[u];j++)
    		{
    			if(h[j]!=1)pd[j]=pd[j]*h[j]%MOD,h[j+1]=h[j+1]*h[j]%MOD,h[j]=1;
    			tmp[pos[u]+j-2]=pd[j-1];
    		}
    		for(int j=2;j<=mxd[u];j++)pd[j]=pd[j]*(sum[pos[u]+j-2]+1)%MOD;
    		if (mxd[u]<n)(h[mxd[u]+1]*=(sum[pos[u]+mxd[u]-2]+1))%=MOD;
    	}
    	for(int i=0;i<=n;i++)pd[i]=1,h[i]=1;
    	for(int i=G[1].size()-1;~i;i--)
    	{
    		int u=G[1][i];
    		for(int j=2;j<=mxd[u];j++)
    		{
    			if(h[j]!=1)pd[j]=pd[j]*h[j]%MOD,h[j+1]=h[j+1]*h[j]%MOD,h[j]=1;
    			ans+=tmp[pos[u]+j-2]*f[pos[u]+j-2]%MOD*(pd[j]-pd[j-1])%MOD;
    		}
    		for(int j=2;j<=mxd[u];j++)pd[j]=pd[j]*(sum[pos[u]+j-2]+1)%MOD;
    		if(mxd[u]<n)(h[mxd[u]+1]*=(sum[pos[u]+mxd[u]-2]+1))%=MOD;
    	}
    	printf("%lld\n",((g[1]-ans)%MOD+MOD)%MOD);
    }
    

  • 相关阅读:
    js截取字符串区分汉字字母代码
    List 去处自定义重复对象方法
    63. Unique Paths II
    62. Unique Paths
    388. Longest Absolute File Path
    41. First Missing Positive
    140. Word Break II
    139. Word Break
    239. Sliding Window Maximum
    5. Longest Palindromic Substring
  • 原文地址:https://www.cnblogs.com/IzayoiDoyo/p/13405121.html
Copyright © 2011-2022 走看看