Loading

笔记-CF1251F Red-White Fence


CF1251F Red-White Fence

大写字母是多项式,否则是变量。


周长等于 \(2\cdot (\) 红板 \(+1+\) 白板数 \()\)

\(s_i\) 表示小于 \(b_i\) 的唯一 \(a_i\) 个数,\(p_i\) 表示小于 \(b_i\) 的出现多次的 \(a_i\) 个数。

所以第 \(i\) 块红板的生成函数应该是:

\[G_i(x)=x^{b_i}(1+2x)^{s_i}(1+x)^{2p_i} \]

总的生成函数是:

\[\begin{aligned}F(x)&=\sum_{i=0}^kG_i(x)\\&=\sum_{i=0}^kx^{b_i}(1+2x)^{s_i}(1+x)^{2p_i}\\&=\sum_{i=0}^kx^{b_i}\left(\sum_{j=0}^{s_i}2^j{s_i\choose j}x^j\right)\left(\sum_{j=0}^{2p_i}{2p_i\choose j}x^j\right)\\\end{aligned} \]

好了好了,原来 \(1\le k\le 5\),那就做完了!


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);i>=0;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
const int N=3e5,mN=N+1,pN=1<<19;
int n,m,q,a[N],cnt[N|1],f[pN<<1],g[pN],h[pN];

//Math
const int mod=998244353;
void fmod(int &x){x+=x>>31&mod;}
int Pow(int a,int x,int res=1){
    for(;x;x>>=1,a=1ll*a*a%mod) (x&1)&&(res=1ll*res*a%mod);
    return res;
}
int fac[mN],ifac[mN],pw2[mN];
void math_init(){
    fac[0]=pw2[0]=1;
    R(i,mN-1) fmod(pw2[i+1]=(pw2[i]<<1)-mod);
    R(i,mN-1) fac[i+1]=(1ll+i)*fac[i]%mod;
    ifac[mN-1]=Pow(fac[mN-1],mod-2);
    L(i,mN-1) ifac[i]=(1ll+i)*ifac[i+1]%mod;
}
int c(int a,int b){
    if(a<0||b<0||b>a) return 0;
    return 1ll*fac[a]*ifac[b]%mod*ifac[a-b]%mod;
}

//Poly
const int G=3,iG=Pow(G,mod-2);
int pn,rev[pN];
void revn(){R(i,pN) rev[i]=(rev[i>>1]>>1)|((i&1)*(pN>>1));}
void ntt(int* p,bool t){
    R(i,pN)if(i<rev[i]) swap(p[i],p[rev[i]]);
    for(int mid=1;mid<pN;mid<<=1)
    for(int wn=Pow(t?iG:G,(mod-1)/(mid<<1)),i=0;i<pN;i+=mid<<1)
    for(int j=i,w=1,x,y;j<(mid|i);j++,w=1ll*w*wn%mod)
        x=p[j],y=1ll*p[mid|j]*w%mod,fmod(p[j]+=y-mod),fmod(p[mid|j]=x-y);
    if(t){int in=Pow(pN,mod-2); R(i,pN) p[i]=1ll*p[i]*in%mod;}
}

//Main
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    revn(),math_init(),cin>>n>>m;
    R(i,n) cin>>a[i],cnt[a[i]]++;
    while(m--){
        int sig=0,pai=0,b; cin>>b;
        R(i,b) if(cnt[i]==1) sig++;
            else if(cnt[i]>=2) pai++;
        R(i,pN) g[i]=h[i]=0;
        R(i,sig+1) g[i]=1ll*c(sig,i)*pw2[i]%mod;
        R(i,pai*2+1) h[i]=c(pai*2,i);
        ntt(g,false),ntt(h,false);
        R(i,pN) g[i]=1ll*g[i]*h[i]%mod; ntt(g,true);
        R(i,(pN<<1)-b) fmod(f[i+b]+=g[i]-mod);
    }
    for(cin>>q;q--;){
        int i; cin>>i,(i>>=1)--;
        cout<<f[i]<<'\n';
    }
    return 0;
}

\[\Huge \rm George1123\ is\ very\ no. \]

posted @ 2020-12-03 13:34  George1123  阅读(1)  评论(0编辑  收藏  举报