Codeforces 1228

Posted blogofchc1234567890

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1228相关的知识,希望对你有一定的参考价值。

D

直接暴力即可
——Qiyang

E

组合计数dp。
\(dp[i][j]=\sum_l=0^j-1 dp[i-1][l]*k^l*C_n-l^j-l*(k-1)^n-l\)

组合计数水题。
考虑容斥可以做到\(O\left(n^2\right)\)
化一下那个柿子可以做到\(O\left(n\log n\right)\)
——Qiyang

F

大力分类讨论。
有一个显然的事情就是根一定是中心。
然后\(\textttcheck\)一下就做完了。
注意一下分类的时候一定要仔细有很多叉点。
——Qiyang

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=140003;
int N,n,deg[maxn],b[5],sz[maxn],depth;
vector<int> g[maxn];
void ensure(bool cond)if(!cond)printf("0\n");exit(0);
void add(int u,int v)
    ensure(u>=1&&u<=n+1&&v>=1&&v<=n+1);
    g[u].push_back(v);
    g[v].push_back(u);

void del(int u,int v)
    ensure(u>=1&&u<=n+1&&v>=1&&v<=n+1);
    g[u].erase(find(g[u].begin(),g[u].end(),v));
    g[v].erase(find(g[v].begin(),g[v].end(),u));

int dfs1(int u,int last,int rt)
    if(u==rt)return -1;
    int mx=0,mxi=0;
    sz[u]=1;
    for(int v:g[u])
        if(v==last)continue;
        if(dfs1(v,u,rt)==-1)
            if(last)return -1;
            else sz[v]=-1;continue;
        
        sz[u]+=sz[v];
        if(sz[v]>mx)mx=sz[v],mxi=v;
    
    return mxi;

int dfs(int u,int last)
    sz[u]=1;
    for(int v:g[u])
        if(v==last)continue;
        int tmp=dfs(v,u);
        if(tmp)sz[u]=-1;return tmp;
        sz[u]+=sz[v];
    
    return sz[u]==(n>>1)?u:0;

bool DFS(int u,int last,int dep)
    if(g[u].size()==1&&last)
//printf("leaf\n");
        if(!depth)depth=dep;
        else if(depth!=dep)return 0;
        return 1;
    
//for(int v:g[u])if(v!=last)printf("%d ",v);puts("");
    if(!((last==0&&g[u].size()==2)||(last&&g[u].size()==3)))return 0;
    for(int v:g[u])
        if(v==last)continue;
        if(!DFS(v,u,dep+1))return 0;
    
    return 1;

bool check(int u)
//printf("check root:%d\n",u);
    depth=0;
    return DFS(u,0,1);

int main()
    scanf("%d",&N);
    n=(1<<N)-2;
    for(int i=1;i<n;i++)
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
        deg[u]++,deg[v]++;
    
    if(n==2)
        printf("2\n1 2");
        return 0;
    
    for(int i=1;i<=n;i++)b[deg[i]]++;
    if(b[2]==2&&b[4]==0)
        int u1=0,u2=0;
        for(u1=1;u1<=n&&deg[u1]!=2;u1++);
        for(u2=u1+1;u2<=n&&deg[u2]!=2;u2++);
        bool flag=0;
        for(int v:g[u1])if(deg[v]==1)flag=1;break;
        if(flag)swap(u1,u2);
        add(u2,n+1);
        ensure(check(u1));
        printf("1\n%d",u2);
    
    else if(b[2]==1&&b[4]==1)
        int u1=0,u2=0,v1=0,v2=0;
        for(u1=1;u1<=n&&deg[u1]!=2;u1++);
        for(u2=1;u2<=n&&deg[u2]!=4;u2++);
        int v3=dfs1(u2,0,u1);
        for(int v:g[u2])if(sz[v]!=-1&&v!=v3)v1==0?(v1=v):(v2=v);
        del(u2,v1);
        del(u2,v2);
        add(u2,n+1);
        add(n+1,v1);
        add(n+1,v2);
        ensure(check(u1));
        printf("1\n%d",u2);
    
    else if(b[2]==0&&b[4]==0)
        int u1=0,u2=0,v1=0,v2=0;
        for(v1=1;v1<=n&&deg[v1]!=1;v1++);
        u1=dfs(v1,0);
        for(int v:g[u1])if(sz[v]==-1)u2=v;break;
        v1=0;
        for(int v:g[u1])if(v!=u2)v1==0?(v1=v):(v2=v);
        del(u1,v1);
        del(u1,v2);
        add(u1,n+1);
        add(n+1,v1);
        add(n+1,v2);
        ensure(check(u1));
        printf("2\n%d %d",min(u1,u2),max(u1,u2));
    
    else ensure(0);
    return 0;

以上是关于Codeforces 1228的主要内容,如果未能解决你的问题,请参考以下文章

codeforces/contest/1228

CodeForces - 1228C(质因数分解+贡献法)

Codeforces 1228

codeforces 1228D - Complete Tripartite

[Codeforces 1228E]Another Filling the Grid (排列组合+容斥原理)

Codeforces 1228C. Primes and Multiplication