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();
    }
    
  • 相关阅读:
    【deep learning精华部分】稀疏自编码提取高阶特征、多层微调完全解释及代码逐行详解
    【machine learning通俗讲解code逐行注释】之线性回归实现
    softmax实现(程序逐句讲解)
    softmax回归(理论部分解释)
    AtomicInteger小小的理解
    jdk8新特性之lambda expressions
    i++ 与 ++i 的从字节码层面看二者的区别
    jdk8永久代从方法区移除的验证
    复杂事件处理引擎—Esper 处理模型
    复杂事件处理引擎—Esper参考(事件部分)
  • 原文地址:https://www.cnblogs.com/DeepThinking/p/13090891.html
Copyright © 2011-2022 走看看