在n场1v1中,假设第i场,有ai个星灵单位,和bi个虫族单位。
tokitsukaze可以在一场1v1中,任选一种种族进行游戏。
如果选择了星灵,那么在这场游戏中,可以选择出兵1到ai个单位。
那么同理,如果选择了虫族,那么在这场游戏中,可以选择出兵1到bi个单位。
tokitsukaze想知道,恰好选择了0,1,2,3,...,个星灵单位的方案数分别是多少。
由于答案很大,所以输出答案mod 998244353 后的结果。
假设所有星灵单位互不相同,所有异虫单位也互不相同。
注意:若两个方案,有其中一个单位不同,即视为不相同。
n<=1e5,ai<=2e5,bi<=1e5,。
考虑生成函数为,
c0即选b[i]的非空子集,方案数
其余ck(1<=k<=ai)即从a[i]中选k个,方案数
放入系数之后,直接分治+NTT即可,
开始试了一发分治+FFT炸了精度
#include
using namespace std;
typedef long long ll;
const int N=1<<18,mod=998244353,G=3;
int n,sum;
int a[N],b[N],fac[N],finv[N];
ll A[N],B[N],inv;
int R[N];
int power(int x,int n)
{
int res=1;
for(;n;n>>=1,x=1ll*x*x%mod)
if(n&1)res=1ll*res*x%mod;
return res;
}
vector colors[N<<1];
struct cmp{
bool operator ()(int a,int b){
return colors[a].size()>colors[b].size();
}
};
priority_queue ,cmp> heap;
void NTT(ll a[],int n,int re){
for (int i=0;i>1;
ll wn=power(G,(mod-1)/i);
if(re) wn=power(wn,(mod-2));
for(int j=0;j &a,vector &b,vector &c){
int n,d;
for (int i=0;i>1]>>1)|((i&1)<<(d-1));
}
for (int i=a.size();i=1;--i)
finv[i]=1ll*finv[i+1]*(i+1)%mod;
}
int C(int n,int m)
{
if(m<0||n=2){
int x=heap.top();
heap.pop();
int y=heap.top();
heap.pop();
NTT_times(colors[x],colors[y],colors[++sz]);
colors[x].clear(),colors[y].clear();
heap.push(sz);
}
for(int i=0;i<=sum;++i)
printf("%d%c",colors[sz][i],i==sum?'\n':' ');
return 0;
}