zoukankan      html  css  js  c++  java
  • JZOJ6438. 【GDOI2020模拟01.16】树上的鼠

    Description

    在这里插入图片描述
    n<=1e6n<=1e6

    Solution

    • 首先考虑简单的情况——一条链。
    • 假设链是奇数长度,如果根在链的中点,那么先手的不管怎么移,后手的都可以移到它的对称点。反之根不在链的中点,先手的就可以移到中点,获得主动权。
    • 假设链长度偶数,那么可以移到远离当前点的两个中点之一,那么接下来的策略也之前的情况是一样的。
    • 那么当且仅当链长度为奇数,且根在中点时先手必败。
    • 推广到一颗树的情况。
    • 可以发现将直径当作上面的链,所有情况都是类似的。
    • 那么当且仅当直径长度为奇数,且根在中点时先手必败。
    • 然后就可以愉快的树形DP了,设f[x][i]f[x][i]表示x的子树最深点深度为ii的方案数。
    • 因为只与深度有关,用长链剖分即可。
    • 合并的时候f[x][i]=sum[y][i1]f[x][i]+sum[x][i1]f[y][i]+f[x][i]f[y][i]f'[x][i]=sum[y][i-1]*f[x][i]+sum[x][i-1]*f[y][i]+f[x][i]*f[y][i]
    • 考虑对于长度比较长的部分的影响相当于是一个后缀乘一个数的形式,打个tag即可。
    • 还要维护前缀和。
    • 最后在根节点的时候是类似的。

    • OJ上爆栈60分
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define maxn 1000005
    #define ll long long 
    #define mo 998244353
    using namespace std;
    
    int n,i,j,k,x,y;
    int em,e[maxn*2],nx[maxn*2],ls[maxn];
    int tot,dfn[maxn],gs[maxn],dep[maxn],mxd[maxn];
    ll f[maxn],g[maxn],h[maxn],s[maxn],c[maxn];
    
    void read(int &x){
    	x=0; char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar());
    	for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    }
    
    void insert(int x,int y){
    	em++; e[em]=y; nx[em]=ls[x]; ls[x]=em;
    	em++; e[em]=x; nx[em]=ls[y]; ls[y]=em;
    }
    
    void DFS1(int x,int p){
    	dep[x]=dep[p]+1,mxd[x]=dep[x],g[x]=1;
    	for(int i=ls[x];i;i=nx[i]) if (e[i]!=p){
    		DFS1(e[i],x),mxd[x]=max(mxd[x],mxd[e[i]]);
    		if (!gs[x]||mxd[e[i]]>mxd[gs[x]])
    			gs[x]=e[i];
    		g[x]=g[x]*(g[e[i]]+1)%mo;
    	}
    }
    
    void DFS2(int x,int p){
    	dfn[x]=++tot;
    	if (gs[x]) DFS2(gs[x],x);
    	for(int i=ls[x];i;i=nx[i]) if (e[i]!=p&&e[i]!=gs[x])
    		DFS2(e[i],x);
    }
    
    void down(int x,int lim){
    	if (h[x]!=1){
    		f[x]=f[x]*h[x]%mo;
    		if (x<lim) h[x+1]=h[x+1]*h[x]%mo;
    		h[x]=1;
    	}
    }
    
    void DFS3(int x,int p){
    	f[dfn[x]]=h[dfn[x]]=s[dfn[x]]=1;
    	if (gs[x]) DFS3(gs[x],x);
    	for(int i=ls[x];i;i=nx[i]) if (e[i]!=p&&e[i]!=gs[x]){
    		DFS3(e[i],x);
    		int y=e[i];
    		for(int j=0;j<=mxd[y]-dep[y];j++){ int k=j+1;
    			down(dfn[y]+j,dfn[y]+mxd[y]-dep[y]),s[dfn[y]+j]=((j>0)*s[dfn[y]+j-1]+f[dfn[y]+j])%mo;
    			if (x==1) continue;
    			down(dfn[x]+k,dfn[x]+mxd[x]-dep[x]),s[dfn[x]+k]=(s[dfn[x]+k-1]+f[dfn[x]+k])%mo;
    			f[dfn[x]+k]=f[dfn[x]+k]*((j>0)*s[dfn[y]+j-1]+1)%mo
    						+f[dfn[y]+j]*s[dfn[x]+k-1]%mo
    						+f[dfn[x]+k]*f[dfn[y]+j]%mo;
    			f[dfn[x]+k]%=mo;
    		}
    		if (x==1) continue;
    		if (mxd[y]<mxd[x])
    			(h[dfn[x]+mxd[y]-dep[x]+1]*=(s[dfn[y]+mxd[y]-dep[y]]+1))%=mo;
    	}
    }
    
    int to[maxn],tmp[maxn];
    void Getans(){
    	for(i=2;i<=mxd[1];i++) 
    		down(i,mxd[1]),s[i]=(i>2)*s[i-1]+f[i];
    	ll ans=1;
    	for(i=0;i<=n;i++) c[i]=1,h[i]=1;
    	for(i=ls[1];i;i=nx[i]) to[++to[0]]=e[i];
    	for(i=1;i<=to[0];i++){ int x=to[i];
    		for(j=2;j<=mxd[x];j++) {
    			if (h[j]!=1) c[j]=c[j]*h[j]%mo,h[j+1]=h[j+1]*h[j]%mo,h[j]=1;
    			tmp[dfn[x]+j-2]=c[j-1];
    		}
    		for(j=2;j<=mxd[x];j++) c[j]=c[j]*(s[dfn[x]+j-2]+1)%mo;
    		if (mxd[x]<n) (h[mxd[x]+1]*=(s[dfn[x]+mxd[x]-2]+1))%=mo;
    	}
    	
    	for(i=0;i<=n;i++) c[i]=1,h[i]=1;
    	for(i=to[0];i;i--){ int x=to[i];
    		for(j=2;j<=mxd[x];j++) {
    			if (h[j]!=1) c[j]=c[j]*h[j]%mo,h[j+1]=h[j+1]*h[j]%mo,h[j]=1;
    			ans+=tmp[dfn[x]+j-2]*f[dfn[x]+j-2]%mo*(c[j]-c[j-1])%mo;
    		}
    		for(j=2;j<=mxd[x];j++) c[j]=c[j]*(s[dfn[x]+j-2]+1)%mo;
    		if (mxd[x]<n) (h[mxd[x]+1]*=(s[dfn[x]+mxd[x]-2]+1))%=mo;
    	}
    	printf("%lld",((g[1]-ans)%mo+mo)%mo);
    }
    
    int main(){
    	read(n);
    	for(i=1;i<n;i++) read(x),read(y),insert(x,y);
    	DFS1(1,0);
    	DFS2(1,0);
    	DFS3(1,0);
    	Getans();
    }
    
  • 相关阅读:
    div 垂直居中的方法
    vs code添加到鼠标右键
    win10系统迁移到新的硬盘
    使用layui iframe弹层,各弹层之前的传值问题
    layui js动态添加的面板不能折叠
    Nginx系列6:对称加密与非对称加密各自的应用场景
    Nginx系列5:从网络原理来看SSL安全协议
    Nginx系列0:Nginx学习历程
    加扰与加密&解扰与解密
    微信小程序学习过程
  • 原文地址:https://www.cnblogs.com/DeepThinking/p/13090891.html
Copyright © 2011-2022 走看看