转载请注明原文地址http://www.cnblogs.com/LadyLex/p/8536399.html
听说今年省选很可怕?刷题刷题刷题
省选已经结束了但是我们要继续刷题刷题刷题
目标是“有思维难度的DP题”!
一,uoj316
这个不用多说……NOI2017的D1T3,难度肯定是有的
个人觉得那个dp方程难想……
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 #define mod 998244353 6 #define K 1010 7 #define L 2048 8 #define RG register 9 #define LL long long 10 inline int quick_mod(int di,int mi) 11 { 12 int ret=1; 13 for(;mi;mi>>=1,di=(LL)di*di%mod) 14 if(mi&1)ret=(LL)ret*di%mod; 15 return ret; 16 } 17 int poww[L],logi[L],rev[L],len=1; 18 inline void dft(int *a,int ra,int opt) 19 { 20 register int i,j,l,d=logi[len]-logi[ra],wn,tmp,*w,*x,*y; 21 for(i=0;i<ra;++i)if(i<(rev[i]>>d))swap(a[i],a[rev[i]>>d]); 22 for(d=2;d<=ra;d<<=1) 23 for(wn=((opt==1)?(len/d):(-len/d)),i=0,l=(d>>1);i<ra;i+=d) 24 for(w=poww+(opt==1?0:len),j=0,x=a+i,y=x+l;j<l;++j,++x,++y,w+=wn) 25 tmp=(LL)(*w)*(*y)%mod,*y=(*x-tmp+mod)%mod,*x=(*x+tmp)%mod; 26 if(opt==-1) 27 for(tmp=quick_mod(ra,mod-2),i=0;i<ra;++i)a[i]=(LL)a[i]*tmp%mod; 28 } 29 int n,k,p,q,pp[K]; 30 int g[K][K],h[K][K],f[K<<1]; 31 inline int min(int a,int b){return a<b?a:b;} 32 int tmp1[L]; 33 inline int get_inv(int *a,int *ret,int ra) 34 { 35 if(ra==1){ret[0]=quick_mod(a[0],mod-2);return 1;} 36 RG int i,la=1,r1=get_inv(a,ret,ra+1>>1); 37 while(la<(ra<<1))la<<=1; 38 memcpy(tmp1,a,ra<<2),memset(tmp1,0,(la-ra)<<2); 39 memset(ret,0,(la-r1)<<2); 40 dft(tmp1,la,1),dft(ret,la,1); 41 for(i=0;i<la;++i)ret[i]=(LL)ret[i]*(2+mod-(LL)tmp1[i]*ret[i]%mod)%mod; 42 dft(ret,la,-1);return ra; 43 } 44 inline void rev_copy(int *to,int *st,int ra) 45 {for(RG int i=0;i<ra;++i,++to)*to=st[ra-i-1];} 46 inline void reverse(int *st,int ra) 47 {for(RG int t,i=0,j=ra-1;i<j;++i,--j)t=st[i],st[i]=st[j],st[j]=t;} 48 int tmp2[L],tmp3[L]; 49 inline int get_mod(int *a,int ra,int *p,int rp,int *ret) 50 { 51 while(ra&&!a[ra-1])--ra; 52 while(rp&&!p[rp-1])--rp; 53 if(ra<rp){memcpy(ret,a,ra<<2),memset(ret+ra,0,(rp-ra)<<2);return rp;} 54 RG int i,j,re=ra-rp+1,la=1; 55 while(la<(re<<1))la<<=1; 56 rev_copy(tmp2,p,rp);memset(tmp2+re,0,(la-re)<<2); 57 get_inv(tmp2,tmp3,re),memset(tmp3+re,0,(la-re)<<2); 58 rev_copy(tmp2,a,ra),memset(tmp2+re,0,(la-re)<<2); 59 dft(tmp3,la,1);dft(tmp2,la,1); 60 for(i=0;i<la;++i)tmp2[i]=(LL)tmp2[i]*tmp3[i]%mod; 61 dft(tmp2,la,-1); 62 la=1;while(la<ra)la<<=1; 63 reverse(tmp2,re), 64 memset(tmp2+re,0,(la-re)<<2); 65 memcpy(tmp3,p,rp<<2),memset(tmp3+rp,0,(la-rp)<<2); 66 dft(tmp2,la,1),dft(tmp3,la,1); 67 for(i=0;i<la;++i)tmp2[i]=(LL)tmp2[i]*tmp3[i]%mod; 68 dft(tmp2,la,-1); 69 for(i=0;i<rp;++i)ret[i]=(a[i]-tmp2[i]+mod)%mod; 70 memset(ret+rp,0,(la-rp)<<2); 71 while(rp&&!ret[rp-1])--rp; 72 return rp; 73 } 74 int c[L],d[L],e[L],tmp[L]; 75 inline int calc(int k) 76 { 77 RG int i,j,u,ra=k+1,r1=k+2,lim,la=1; 78 memset(g,0,sizeof(g)); 79 memset(h,0,sizeof(h)); 80 g[k][1]=(LL)pp[k]*q%mod; 81 g[k][0]=h[k][0]=1; 82 for(i=k-1;i>0;--i) 83 { 84 ra=k/i,g[i][0]=h[i][0]=1; 85 for(j=1;j<=ra;++j) 86 for(u=0;u<j;++u) 87 h[i][j]=(h[i][j]+(LL)h[i][u]*g[i+1][j-u-1]%mod*pp[i]%mod*q)%mod; 88 for(j=1;j<=ra;++j) 89 for(u=0;u<=j;++u) 90 g[i][j]=(g[i][j]+(LL)h[i][u]*g[i+1][j-u])%mod; 91 } 92 memset(f,0,sizeof(f)),f[0]=1; 93 for(i=1;i<=(ra<<1);++i) 94 for(j=1,lim=min(k+1,i);j<=lim;++j) 95 f[i]=(f[i]+(LL)f[i-j]*g[1][j-1]%mod*q)%mod; 96 int ret=0; 97 if(n<=(ra<<1)) 98 { 99 for(i=max(0,n-k);i<=n;++i) 100 ret=(ret+(LL)f[i]*g[1][n-i])%mod; 101 return ret; 102 } 103 memset(c,0,sizeof(c)),c[1]=1; 104 memset(d,0,sizeof(d));d[ra]=1; 105 for(i=1;i<=ra;++i)d[ra-i]=(LL)q*g[1][i-1]%mod; 106 memset(e,0,sizeof(e)),e[0]=1; 107 while(la<(ra<<1))la<<=1; 108 for(lim=n-k-1;lim;lim>>=1) 109 { 110 if(lim&1) 111 { 112 memcpy(tmp,c,k<<2);memset(tmp+k,0,(la-k)<<2); 113 dft(e,la,1),dft(tmp,la,1); 114 for(i=0;i<la;++i)e[i]=(LL)e[i]*tmp[i]%mod; 115 dft(e,la,-1); 116 get_mod(e,k<<1,d,ra,e); 117 } 118 dft(c,la,1); 119 for(i=0;i<la;++i)c[i]=(LL)c[i]*c[i]%mod; 120 dft(c,la,-1); 121 get_mod(c,k<<1,d,ra,c); 122 } 123 124 } 125 int main() 126 { 127 RG int i,x,y; 128 scanf("%d%d%d%d",&n,&k,&x,&y);logi[1]=0; 129 while(len<=(k+1<<1))len<<=1,logi[len]=logi[len>>1]+1; 130 poww[0]=poww[len]=1,poww[1]=quick_mod(3,(mod-1)/len); 131 for(i=2;i<len;++i)poww[i]=(LL)poww[i-1]*poww[1]%mod; 132 for(i=0;i<len;++i) 133 if(i&1)rev[i]=(rev[i>>1]>>1)|(len>>1); 134 else rev[i]=(rev[i>>1]>>1); 135 p=(LL)x*quick_mod(y,mod-2)%mod,q=(LL)(y-x)*quick_mod(y,mod-2)%mod; 136 for(pp[0]=1,pp[1]=p,i=2;i<=k;++i)pp[i]=(LL)pp[i-1]*p%mod; 137 printf("%d\n",(calc(k)-calc(k-1)+mod)%mod); 138 }