洛谷P6017 仙人掌(组合数学)

首先研究一下subtask 5怎么搞。

手玩一下不难发现:满足总和为$2m-2$且每个数不小于1的数列都是满足要求的。这就给了我们启发:可不可以直接找出度数序列数量呢?

接下来解决一个问题:$n$个结点的仙人掌最多有几条边?

不难发现,所有包含点数大于4个的环都是不优的,例如5个点的环可以改成6条边的两个环:

这样就可以得到,$n$为奇数时,$m=\frac{3}{2}(n-1)$:

$n$为偶数时,$m=\frac{3}{2}n-2$:

同时,不难发现,若所有结点的度数均为偶数,这样的仙人掌必定存在(找出度数最大的3个点,连一个环,缩成一个点,一路执行下去就可以了)

对于奇数点,我们发现,把奇数点像下图一样两两配对,就可以转化到偶数的情况:

(合并两个蓝点,就转化为第二个图)

不过这样有例外:对于度为1的点,我们不能另找一个度为1的点配对(不然就不连通了),只能找一个度更大的奇数点或把它拼到偶数点上去。

那么,结果只跟$n$,$m$,1点个数$c_1$,奇数点个数$c_{odd}$有关,直接DP是$O(n^4)$的,考虑优化求所有结点的度数均为偶数的序列个数的部分。

把每个点的度除以2,那么就变成了把$m$个无差别的小球放入$n$个无差别的口袋,每个口袋至少有一个球的方案数,依据隔板法,答案为$C^{n-1}_{m-1}$。

对于原问题,我们首先求出$n'=n-c_1,m'=m-\frac{c_1+c_{odd}}{2}$的全为偶数的方案数,然后在$n'$个中找$c_{odd}$个变成奇数(方案数$C^{c_{odd}}_{n'}$),再加上$c_1$个度为1的点(方案数$C^{c_1}_{n}$),这样就可以$O(n^2)$计算啦

#include<cstdio>
#define For(i,A,B) for(i=(A);i<=(B);++i)
typedef long long ll;
const int mod=998244353;
int f[3005],g[3005];
void exgcd(int a,int b,int &x,int &y){
    if(!b){x=1;y=0;}
    else{
        exgcd(b,a%b,y,x);
        y-=a/b*x;
    }
}
inline int inv(int a){
    int x,y;
    exgcd(a,mod,x,y);
    return x<0?x+mod:x;
}
inline int C(int m,int n){return m<=n?(ll)f[n]*g[m]%mod*g[n-m]%mod:0;}
inline int maxm(int n){return n&1?(n-1>>1)*3:(n>>1)*3-2;}
inline bool check(int n,int m,int c1,int co){  //检查转化后是否是合法情况
    if(c1>co){n-=c1;m-=c1;}  //1点太多,只能去和偶数点配对
    else{n-=c1+co>>1;m-=c1+co>>1;}
    return m>=n-1&&m<=maxm(n);
}
int main(){
    int T,n,m,nn,mm,i,j,ans;
    scanf("%d",&T);
    f[0]=f[1]=g[0]=g[1]=1;
    For(i,2,2997)f[i]=(ll)f[i-1]*i%mod;
    g[2997]=inv(f[2997]);
    for(i=2996;i>1;--i)g[i]=(ll)g[i+1]*(i+1)%mod;
    while(T--){
        scanf("%d%d",&n,&m);
        if(m<n-1||m>maxm(n)){
            puts("0");
            continue;
        }
        ans=0;
        For(i,0,n-1)
            For(j,0,n-i)if(i+j*3<=(m<<1))if(!(i+j&1)&&check(n,m,i,j)){
                nn=n-i;mm=m-(i+j>>1);
                ans=(ans+(ll)C(nn-1,mm-1)*C(i,n)%mod*C(j,nn))%mod;
            }else;
            else break;
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

posted @ 2020-02-10 13:54  wangyuchen  阅读(236)  评论(0编辑  收藏  举报