转载请注明原文地址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 }
uoj316

相关文章: