• 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]);
    }
    
  • 相关阅读:
    epoll讲解
    Majority Element
    Excel Sheet Column Title
    Git链接到自己的Github(2)进阶使用
    Git链接到自己的Github(1)简单的开始
    直接管理内存
    Oracle 11g 编译使用BBED
    Oracle数据库该如何着手优化一个SQL
    Oracle配置数据库诊断
    Oracle 数据库重放(Database Replay)功能演示
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12592156.html
Copyright © 2020-2023  润新知