• CF755G PolandBall and Many Other Balls 题解


    Codeforces
    Luogu

    Description.

    \(n\) 个球,构造若干组满足:

    1. 每组至多两个球至少一个球
    2. 不存在一个球出现在多个组
    3. 如果一组有两个球,这两个球相邻

    问为 \(k\in[0,M]\) 的方案数。

    Solution.

    首先,有个显然的 dp 为 \(dp_{i,j}=dp_{i-1,j}+dp_{i-1,j-1}+dp_{i-2,j-1}\)
    可以考虑成有一个网格每次可以走 \(\vec v=(1,0),(2,1),(1,1)\),求方案数。
    考虑枚举 \((2,1)\) 个数为 \(k\),则有答案为

    \[\begin{aligned} &=\sum_{k=0}^m\dbinom{n-2k}{m-k}\dbinom{n-k}{k}\\ &=\sum_{k=0}^m\dbinom{n-k}{m}\dbinom{m}{k} \end{aligned} \]

    接下来参考了这篇题解
    组合意义是先从前 \(m\) 个选出了若干个,然后从剩下的里再选出 \(m\) 个的方案数。
    可以考虑容斥,钦定 \(k\) 个必须重复选,剩下随意。
    方案数是 \(\dbinom{m}{k}2^{m-k}\dbinom{n-k}{m-k}\),分别为:前 \(m\) 个里钦定 \(k\) 个重复,前 \(m\) 个里除了 \(k\) 个之外随意,剩下里选出不重复的。

    \[\therefore\begin{aligned} &=\sum_{k=0}^m(-1)^k\dbinom{m}{k}\dbinom{n-k}{m-k}2^{m-k}\\ &=m!n^{\underline{m}}\sum_{k=0}^m\frac{(-1)^k}{k!n^{\underline k}}\frac{2^{m-k}}{(m-k)!^2} \end{aligned} \]

    Coding.

    点击查看代码
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    const int P=998244353,N=32768;
    int fc[N],fi[N],iv[N];//dbinit{{{
    inline int ksm(int x,int q=P-2) {int r=1;for(;q;q>>=1,x=1ll*x*x%P) if(q&1) r=1ll*r*x%P;return r;}
    inline void dbinit(int n=N-1)
    {
    	fc[0]=1;for(int i=1;i<=n;i++) fc[i]=1ll*fc[i-1]*i%P;
    	iv[1]=1;for(int i=2;i<=n;i++) iv[i]=1ll*iv[P%i]*(P-P/i)%P;
    	fi[0]=1;for(int i=1;i<=n;i++) fi[i]=1ll*fi[i-1]*iv[i]%P;
    }
    inline int C(int n,int m) {return n<0||m<0||n<m?0:1ll*fc[n]*fi[m]%P*fi[n-m]%P;}//}}}
    namespace poly//{{{
    {
    	const int P=998244353,G=3,L=119,Z=23;int rev[N],g[Z+5][2];
    	inline void init(int T)
    	{
    		rev[0]=0;for(int i=1;i<T;i++) rev[i]=(rev[i>>1]>>1)|((i&1)?(T>>1):0);
    		if(g[Z][0]) return;else g[Z][0]=ksm(G,L),g[Z][1]=ksm(ksm(G),L);
    		for(int i=Z;i;i--) g[i-1][0]=1ll*g[i][0]*g[i][0]%P,g[i-1][1]=1ll*g[i][1]*g[i][1]%P;
    	}
    	#define fst(x) ((x)>=P?(x)-P:(x))
    	inline void NTT(int T,int *a,int flg)
    	{
    		for(int i=0;i<T;i++) if(rev[i]>i) swap(a[i],a[rev[i]]);
    		for(int d=1,rp=1;d<T;d<<=1,rp++)
    			for(int i=0,wn=g[rp][flg];i<T;i+=(d<<1))
    				for(int k=0,w=1;k<d;k++,w=1ll*w*wn%P)
    					{int x=a[i+k],y=1ll*a[i+k+d]*w%P;a[i+k]=fst(x+y),a[i+k+d]=fst(x-y+P);}
    		if(flg) {int iv=ksm(T);for(int i=0;i<T;i++) a[i]=1ll*a[i]*iv%P;}
    	}
    }//}}}
    int n,K,A[N<<1],B[N<<1];
    int main()
    {
    	read(n,K),dbinit();int vl=1,T=1;while(T<=K+K) T<<=1;poly::init(T);
    	for(int k=0;k<=K;k++)
    	{
    		A[k]=1ll*fi[k]*vl%P,A[k]=(k&1?P-A[k]:A[k]);
    		B[k]=1ll*ksm(2,k)*fi[k]%P*fi[k]%P;
    		vl=1ll*vl*ksm(n-k)%P;
    	}
    	poly::NTT(T,A,0),poly::NTT(T,B,0);for(int i=0;i<T;i++) A[i]=1ll*A[i]*B[i]%P;
    	poly::NTT(T,A,1),vl=1;for(int i=0;i<T;i++) A[i]=1ll*vl*A[i]%P*fc[i]%P,vl=1ll*vl*(n-i)%P;
    	for(int i=1;i<=K;i++) printf("%d%c",A[i],i==K?'\n':' ');
    	return 0;
    }
    
  • 相关阅读:
    基于小脚丫DDS 调频 调幅 调相 切换波形 AD5601输出模拟波形
    spi 10方式编写
    VGA colorbar显示
    hostname
    让CentOS能用yum自动安装rar和unrar
    Centos系统使用代理上网时 yum的代理设置
    【转】uvm 与 system verilog的理解
    跟我一起学习VIM
    gVim 配置方案 采用Vundle管理插件
    在 Ubuntu 16.04 中安装谷歌 Chrome 浏览器
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15498563.html
Copyright © 2020-2023  润新知