CTS2019珍珠
Posted weiyanpeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CTS2019珍珠相关的知识,希望对你有一定的参考价值。
不难发现我们需要一个选奇数/偶数个的egf
这个分别是 $\frac e^x - e^-x 2 $ 和 $\frac e^x + e^-x 2 $。
然后就可以开始推式子了。
答案是
\[ n!\sum _k=0^n-2m(\frac e^x + e^-x 2+y\frac e^x - e^-x 2)^D [x^n][y^k] \]
\[ = n! \frac 12^D \sum _k=0^n-2m \sum _i=0^D e^(2i-D)x (1+y)^i(1-y)^D-i[x^n][y^k] \]
\[ = \frac 12^D \sum_i=0^D \binom Di(2i-D)^n \sum _k=0^n-2m (1+y)^i(1-y)^D-i[y^k] \]
好了,考虑如何计算这个东西。
首先将\((1-y)^D\)计算出来,因为$ (1+y)/(1-y) = 1 + 2y + 2y^2 + 2y^3 + ...$
设 \(lim = n-2m\)
我们可以轻易的算出贡献
枚举i, 枚举有多少次是2(至少多加了1)
有:
\[
ans*2^D = \sum _i=0^D \binom Di (2i-D)^n \sum_p^D ff[p] \sum_k=0^D \binom lim-pk 2^k \binomik
\]
交换第二三个和号,并且将只与一个变量相关的弄到一起,最后会形成如下形式:
\[ ans*2^D = \sum _i=0^D A(i) \sum_p^D B(p) \frac1(i-p)!\sum_k=0^D C(k) \frac1(lim-p-k)! \]
其中,\(A,B,C\)是三个多项式
将sigma_p后的部分当作f(p),f(p)可以通过C与\(e^x\)卷积得到,之后再卷积一次就能得出答案
复杂度一个log
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353,g=3;
inline int add(int a,int b)a+=b;return a>=mod?a-mod:a;
inline int sub(int a,int b)a-=b;return a<0?a+mod:a;
inline int mul(int a,int b)return (ll)a*b%mod;
inline int qpow(int a,int b)int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;
const int inv2=qpow(2,mod-2);
/* math */
typedef vector<int> poly;
namespace poly_template
int rev[4000010];
void DFT(int *t,int n,int type)
int l=0;while(1<<l<n)++l;
for(int i=1;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
for(int i=0;i<n;i++)if(i<rev[i])swap(t[i],t[rev[i]]);
for(int step=1;step<n;step<<=1)
int wn=qpow(g,(mod-1)/(step<<1));
for(int i=0;i<n;i+=step*2)for(int j=0,w=1;j<step;j++,w=mul(w,wn))
int x=t[i+j],y=mul(w,t[i+j+step]);
t[i+j]=add(x,y),t[i+j+step]=sub(x,y);
if(type==1)return ;for(int i=1;i<n-i;i++)swap(t[i],t[n-i]);
int inv=qpow(n,mod-2);for(int i=0;i<n;i++)t[i]=mul(t[i],inv);
inline poly NTT(poly A,int n,poly B,int m)
poly ret;
int l=0;while(1<<l<n+m)++l;
A.resize(1<<l),B.resize(1<<l),ret.resize(1<<l);
DFT(&A[0],1<<l,1);DFT(&B[0],1<<l,1);
for(int i=0;i<1<<l;i++)ret[i]=mul(A[i],B[i]);
DFT(&ret[0],1<<l,-1);
ret.resize(n+m-1);
return ret;
inline poly NTT(poly A,poly B)return NTT(A,A.size(),B,B.size());
using namespace poly_template;
int D,n,m;
int fac[4000010],ifac[4000010];
inline void binom_init(int n=4000000)
fac[0]=ifac[0]=1;for(int i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
ifac[n]=qpow(fac[n],mod-2);for(int i=n-1;i;i--)ifac[i]=mul(ifac[i+1],i+1);
inline int binom(int a,int b)
if(b>a)return 0;
return mul(fac[a],mul(ifac[b],ifac[a-b]));
poly G,ff,Fac,F;
int main()
binom_init();
cin >> D >> n >> m;
if(n<2*m)printf("%d\n",0);return 0;
if(D<=n-2*m+1)printf("%d\n",qpow(D,n));return 0;
ff.resize(D+1);G.resize(D+1);Fac.resize(D+1);F.resize(D+1);
int lim=n-2*m;
for(int i=0;i<=min(D,n-2*m);i++)
ff[i]=binom(D,i);
if(i&1)ff[i]=mod-ff[i];
ff[i]=mul(ff[i],fac[lim-i]);
for(int i=0;i<=D;i++)G[i]=mul(qpow(2,i),mul(ifac[i],ifac[i])), Fac[i]=ifac[i];
ff=NTT(ff,Fac);
for(int i=0;i<=D;i++)G[i]=mul(G[i],lim-i>=0?ff[lim-i]:0);
for(int i=0;i<=D;i++)F[i]=mul(mul(fac[D],ifac[D-i]),qpow(1ll*(mod+2*i-D)%mod,n));
G=NTT(Fac,G);
int ans=0;
for(int i=0;i<=D;i++)
ans=add(ans,mul(F[i],G[i]));
ans=mul(ans,qpow(inv2,D));
cout << ans << endl;
return 0;
以上是关于CTS2019珍珠的主要内容,如果未能解决你的问题,请参考以下文章
loj3120. 「CTS2019 | CTSC2019」珍珠
CTS测试CtsWindowManagerDeviceTestCases模块的testShowWhenLockedImeActivityAndShowSoftInput测试fail项解决方法(代码片段