当前位置: 代码迷 >> 综合 >> 【容斥】【数学】Atcoder ARC102 Stop. Otherwise...
  详细解决方案

【容斥】【数学】Atcoder ARC102 Stop. Otherwise...

热度:55   发布时间:2023-09-27 06:24:40.0

题意:

有N个K个面的骰子,当i=2,3,4……2*k时,
求所有骰子的点数中,没有任何两个之和为i的方案数。这N个骰子不互相区分(即1,2与2,1是同一种情况)


分析:

很简单的一道容斥题(无奈D看错题意调太久。。。)

任何两个加起来不为i,所以这题就简单了。无非就是说对于jj,要求 i ? j 与它不能同时出现(i为偶数时,分两种情况讨论,即存在一个i2i2和不存在i2i2)。然后就可以算出矛盾的对数,即k2=min{ k??i2?,?i?12?}k2=min{k??i2?,?i?12?}

然后没有影响的种类就有k1=k?k2?2?[i%2==0]k1=k?k2?2?[i%2==0]

现在问题转化为:求(k1+k2种颜色,N个骰子的方案数,即Ck1+k2?1N+k1+k2?1CN+k1+k2?1k1+k2?1×2k2×2k2,但就这样算会出现重复,因为可能那k2k2种颜色中,并没有全部用过,因此在乘上2k22k2后,对某个方案而言,有jj个没用过,就会重复计算 2 j 次。

所以就可以开心地容斥啦
下面给一个总式子

ansi=j=0jk2(?1)jCk1+k2?j?1N+k1+k2?j?1?2k2?j?Cjk2ansi=∑j=0j≤k2(?1)jCN+k1+k2?j?1k1+k2?j?1?2k2?j?Ck2j

#include<cstdio>
#include<cstring>
#include<algorithm>
#define SF scanf
#define PF printf
#define MAXN 2010
#define MOD 998244353
using namespace std;
typedef long long ll;
ll C[2*MAXN][2*MAXN],bits[2*MAXN];
int n,k;
ll count(int s,int tot){return C[s+tot-1][s-1]; 
}
ll solve(int i,int tot){int k2=min(k-i/2,(i-1)/2);int k1=k-k2*2-((i%2)==0);ll flag=1;ll res=0;for(int l=k2;l+k1>0&&l>=0;l--,flag=-flag){res+=flag*count(l+k1,tot)*bits[l]%MOD*C[k2][l]%MOD;res%=MOD;}return (res+MOD)%MOD;
}
int main(){SF("%d%d",&k,&n);int sum=0;bits[0]=1;for(int i=1;i<=4000;i++)bits[i]=bits[i-1]*2ll%MOD;C[0][0]=1;for(int i=1;i<=4000;i++){C[i][0]=1;for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%MOD;}ll ans=0;for(int i=2;i<=2*k;i++){if(i%2==0){ans=(solve(i,n)+solve(i,n-1))%MOD;}else{ans=solve(i,n);}PF("%lld\n",ans);}
}
  相关解决方案