Gym101620E Embedding Enumeration

Link
分类巨讨论zsbd。Link

#include<cmath>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
const int N=300007,P=1000000007;
std::vector<int>e[N],pos[N];int n,dep[N],ch[N],len[N],fib[N],coef[N],vis[N],f[N];
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
int add(int a,int b){return inc(a,b),a;}
int mul(int a,int b){return 1ll*a*b%P;}
void dfs1(int u,int fa)
{
    dep[u]=dep[fa]+1,ch[u]=u;
    for(int v:e[u]) if(v^fa) if(dfs1(v,u),e[u].size()==2) len[u]=len[v]+1,ch[u]=ch[v];
    pos[ch[u]].push_back(u);
}
int dfs2(int u)
{
    if(vis[u]) return f[u];vis[u]=1;
    int t=ch[u],l=len[u],c1=0,c2=0,c3=0,c4=0,f1,f2,f3,f4,l1,l2,l3,l4;
    if(e[t].size()>3) return 0;
    if(e[t].size()==1) return f[u]=coef[l+1];
    for(int v:e[t]) if(dep[v]>dep[t]) (c1? c2:c1)=v;
    if(e[c1].size()>3||e[c2].size()>3||e[c1].size()+e[c2].size()==6) return 0;
    if(e[c1].size()<=2&&e[c2].size()<=2)
    {
	f1=e[ch[c1]].size()==1,f2=e[ch[c2]].size()==1,l1=len[c1],l2=len[c2];
	if(f1&&l1<=l&&l1) inc(f[u],mul(fib[l-l1],dfs2(c2)));
	if(f2&&l2<=l&&l2) inc(f[u],mul(fib[l-l2],dfs2(c1)));
	if(f1&&f2) inc(f[u],mul(fib[l],add(coef[abs(l2+1-l1)],coef[abs(l1+1-l2)])));
	else
	{
	    if(f2) std::swap(c1,c2),std::swap(f1,f2),std::swap(l1,l2);
	    if(l1<=l2) inc(f[u],mul(fib[l],dfs2(pos[ch[c2]][l2-l1])));
	    if(l1+2<=l2) inc(f[u],mul(fib[l],dfs2(pos[ch[c2]][l2-l1-2])));
	}
	if(f1&&l>=l1+2) inc(f[u],mul(fib[l-l1-2],dfs2(c2)));
	if(f2&&l>=l2+2) inc(f[u],mul(fib[l-l2-2],dfs2(c1)));
    }
    else
    {
	if(e[c1].size()==3) std::swap(c1,c2);
	f1=e[ch[c1]].size()==1,l1=len[c1];
	if(f1&&l1<=l) inc(f[u],mul(fib[l-l1],dfs2(c2)));
	for(int v:e[c2]) if(dep[v]>dep[c2]) (c3? c4:c3)=v;
	f3=e[ch[c3]].size()==1,f4=e[ch[c4]].size()==1,l3=len[c3],l4=len[c4],l1+=f1;
	for(int i=0;i<2;++i)
	{
	    if(f3&&l3+1<=l)
		if(f1&&f4) inc(f[u],mul(fib[l-l3-1],coef[abs(l1-l4-1)]));
		else if(f1&&l1<=l4) inc(f[u],mul(fib[l-l3-1],dfs2(pos[ch[c4]][l4-l1])));
		else if(f4&&l4+1<=l1) inc(f[u],mul(fib[l-l3-1],dfs2(pos[ch[c1]][l1-l4-1])));
	    std::swap(c3,c4),std::swap(f3,f4),std::swap(l3,l4);
	} 
	if(f1&&l>=l1+1) inc(f[u],mul(fib[l-l1-1],dfs2(c2)));;
    }
    return f[u];
}
int main()
{
    int n=read(),sum[2];fib[0]=fib[1]=coef[0]=coef[1]=sum[0]=sum[1]=1,e[0].push_back(1),e[1].push_back(0);
    for(int i=1,u,v;i<n;++i) u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
    for(int i=2;i<=n;++i) inc(fib[i]=fib[i-1],fib[i-2]),inc(sum[i&1],fib[i]),inc(coef[i]=sum[i&1],P-fib[i-2]);
    dfs1(1,0),dfs2(1);
    printf("%d",f[1]);
}
posted @ 2020-03-29 14:28  Shiina_Mashiro  阅读(157)  评论(0编辑  收藏  举报