总结:
D1T1T2的思路较为好想,D1T3考试时估计是战略放弃的对象,D2T1思路容易卡在优化状态上(虽然明显3n的状态中有很多无用状态,从而想到子集最优,选择子集最优容易发现反例,从而考虑连带周边一起考虑,去年考场上想出来的,今年却想不出来***)但50十分容易,D2T2的式子超出目前水平(多项式的式子推法需要继续加强),D2T3在学过MinMax容斥以及树上高斯消元(好像还需要FWT)后较为简单,目前水平在250-380中来回飘荡,感觉pkuwc2019要完。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define X first 5 #define Y second 6 #define N 300005 7 #define P 998244353 8 struct st{int l,r,v,tg;}T[N*20]; 9 int n,cc,tt,ans,p[N],d[N],ch[N][2],rt[N]; 10 pair<int,int>q[N]; 11 int pw(int a,int b){int r=1;for(;b;b>>=1,a=1ll*a*a%P)if(b&1)r=1ll*r*a%P;return r;} 12 int sqr(int x){return 1ll*x*x%P;} 13 void down(int x) 14 { 15 if(T[x].tg!=1) 16 { 17 T[T[x].l].tg=1ll*T[T[x].l].tg*T[x].tg%P; 18 T[T[x].l].v=1ll*T[T[x].l].v*T[x].tg%P; 19 T[T[x].r].tg=1ll*T[T[x].r].tg*T[x].tg%P; 20 T[T[x].r].v=1ll*T[T[x].r].v*T[x].tg%P; 21 T[x].tg=1; 22 } 23 } 24 void upd(int &x,int l,int r,int p) 25 { 26 x=++cc;T[x].v=T[x].tg=1; 27 if(l==r)return; 28 int mid=l+r>>1; 29 if(p<=mid)upd(T[x].l,l,mid,p);else upd(T[x].r,mid+1,r,p); 30 } 31 int merge(int x,int y,int p,int pl1,int pl2,int pr1,int pr2) 32 { 33 if(!x&&!y)return 0; 34 if(x&&!y) 35 { 36 int q=(P+1-p),r=(1ll*p*pl2+1ll*q*pr2)%P; 37 T[x].v=1ll*T[x].v*r%P; 38 T[x].tg=1ll*T[x].tg*r%P; 39 return x; 40 } 41 if(!x&&y) 42 { 43 int q=(P+1-p),r=(1ll*p*pl1+1ll*q*pr1)%P; 44 T[y].v=1ll*T[y].v*r%P; 45 T[y].tg=1ll*T[y].tg*r%P; 46 return y; 47 } 48 down(x);down(y); 49 int r1=T[T[x].r].v,r2=T[T[y].r].v,r3=T[T[x].l].v,r4=T[T[y].l].v; 50 T[x].l=merge(T[x].l,T[y].l,p,pl1,pl2,(pr1+r1)%P,(pr2+r2)%P); 51 T[x].r=merge(T[x].r,T[y].r,p,(pl1+r3)%P,(pl2+r4)%P,pr1,pr2); 52 T[x].v=(T[T[x].l].v+T[T[x].r].v)%P;return x; 53 } 54 void dfs(int x) 55 { 56 if(d[x]==0)return; 57 if(d[x]==1){dfs(ch[x][0]);rt[x]=rt[ch[x][0]];return;} 58 dfs(ch[x][0]);dfs(ch[x][1]); 59 rt[x]=merge(rt[ch[x][0]],rt[ch[x][1]],p[x],0,0,0,0); 60 } 61 void qry(int x,int l,int r) 62 { 63 if(!x)return; 64 if(l==r){ans=(ans+1ll*l*q[l].X%P*sqr(T[x].v))%P;return;} 65 int mid=l+r>>1;down(x);qry(T[x].l,l,mid);qry(T[x].r,mid+1,r); 66 } 67 int main() 68 { 69 scanf("%d",&n); 70 for(int i=1,fa;i<=n;i++)scanf("%d",&fa),ch[fa][d[fa]++]=i; 71 int iv=pw(10000,P-2); 72 for(int i=1;i<=n;i++)scanf("%d",&p[i]); 73 for(int i=1;i<=n;i++)if(!d[i])q[++tt]=make_pair(p[i],i);else p[i]=1ll*p[i]*iv%P; 74 sort(q+1,q+tt+1); 75 for(int i=1;i<=tt;i++)upd(rt[q[i].Y],1,tt,i); 76 dfs(1);qry(rt[1],1,tt);printf("%d\n",ans); 77 return 0; 78 }
loj#2538. 「PKUWC2018」Slay the Spire
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 3005 4 #define mod 998244353 5 int n,m,k,a[N],b[N],f[N][N],g[N][N],s[N],C[N][N]; 6 bool cmp(int a,int b){return a>b;} 7 int calcf(int a,int b) 8 { 9 if(!b)return C[n][a]; 10 int r=0; 11 for(int i=1;i<=n;i++)(r+=1ll*f[b][i]*C[n-i][a-b]%mod)%=mod; 12 return r; 13 } 14 int calcg(int a,int b) 15 { 16 if(!b)return 0; 17 int r=0; 18 for(int i=1;i<=n;i++)(r+=1ll*g[b][i]*C[n-i][a-b]%mod)%=mod; 19 return r; 20 } 21 int main() 22 { 23 for(int i=0;i<=3000;i++)C[i][0]=1; 24 for(int i=1;i<=3000;i++)for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; 25 int T;scanf("%d",&T); 26 while(T--) 27 { 28 scanf("%d%d%d",&n,&m,&k); 29 for(int i=1;i<=n;i++)scanf("%d",&b[i]); 30 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 31 sort(b+1,b+n+1,cmp);sort(a+1,a+n+1,cmp); 32 s[0]=0; 33 for(int i=1;i<=n;i++)f[1][i]=b[i],s[i]=(s[i-1]+f[1][i])%mod; 34 for(int i=2;i<=n;i++) 35 { 36 for(int j=1;j<=n;j++)f[i][j]=1ll*b[j]*s[j-1]%mod; 37 for(int j=1;j<=n;j++)s[j]=(s[j-1]+f[i][j])%mod; 38 } 39 for(int i=1;i<=n;i++)g[1][i]=a[i],s[i]=(s[i-1]+g[1][i])%mod; 40 for(int i=2;i<=n;i++) 41 { 42 for(int j=1;j<=n;j++)g[i][j]=(1ll*a[j]*C[j-1][i-1]+s[j-1])%mod; 43 for(int j=1;j<=n;j++)s[j]=(s[j-1]+g[i][j])%mod; 44 } 45 int ans=0; 46 for(int i=0;i<=n&&i<=m;i++) 47 { 48 int j=m-i;if(j>n)continue; 49 if(i<k)(ans+=1ll*calcf(i,i)*calcg(j,k-i)%mod)%=mod;else (ans+=1ll*calcf(i,k-1)*calcg(j,1)%mod)%=mod; 50 } 51 printf("%d\n",ans); 52 } 53 return 0; 54 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int N=1200005,P=998244353; 5 int n,m,nn,mx[N],sz[N],e[30],f[N],fac[50],ifac[50]; 6 int pw(int a,int b){int r=1;for(;b;b>>=1,a=1ll*a*a%P)if(b&1)r=1ll*r*a%P;return r;} 7 int A(int a,int b){return 1ll*fac[a]*ifac[a-b]%P;} 8 int main() 9 { 10 scanf("%d%d",&n,&m);nn=(1<<n); 11 for(int i=1,u,v;i<=m;i++)scanf("%d%d",&u,&v),u--,v--,e[u]|=(1<<v),e[v]|=(1<<u); 12 for(int i=0;i<n;i++)e[i]|=(1<<i); 13 for(int i=fac[0]=1;i<=30;i++)fac[i]=1ll*fac[i-1]*i%P; 14 ifac[30]=pw(fac[30],P-2); 15 for(int i=30;i;i--)ifac[i-1]=1ll*ifac[i]*i%P; 16 for(int i=0;i<nn;i++)for(int j=0;j<n;j++)if(i>>j&1)sz[i]++; 17 f[0]=1; 18 for(int i=0;i<nn;i++)if(f[i])for(int j=0;j<n;j++)if(!(i>>j&1)) 19 { 20 int t=i|e[j]; 21 if(mx[t]<mx[i]+1)f[t]=0,mx[t]=mx[i]+1; 22 if(mx[t]==mx[i]+1)f[t]=(f[t]+1ll*f[i]*A(n-sz[i]-1,sz[e[j]]-sz[i&e[j]]-1))%P; 23 } 24 int ans=1ll*f[nn-1]*ifac[n]%P; 25 printf("%d\n",ans); 26 return 0; 27 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1000005,mod=998244353; 4 int n,ans,w[N],sum[N],f[N],r[N]; 5 int pw(int a,int b){int r=1;for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)r=1ll*r*a%mod;return r;} 6 void ntt(int n,int *a,int f) 7 { 8 int l=0;while((1<<l)<n)l++; 9 for(int i=1;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1)); 10 for(int i=0;i<n;i++)if(i<r[i])swap(a[i],a[r[i]]); 11 for(int i=2;i<=n;i<<=1) 12 { 13 int wn=pw(3,(mod-1)/i); 14 if(f==-1)wn=pw(wn,mod-2); 15 for(int j=0;j<n;j+=i)for(int k=0,w=1;k<(i>>1);k++,w=1ll*w*wn%mod) 16 { 17 int u=a[j+k],v=1ll*a[j+k+(i>>1)]*w%mod; 18 a[j+k]=(u+v)%mod;a[j+k+(i>>1)]=(u+mod-v)%mod; 19 } 20 } 21 if(f==-1)for(int i=0,iv=pw(n,mod-2);i<n;i++)a[i]=1ll*a[i]*iv%mod; 22 } 23 int gt(int L,int R) 24 { 25 int l=L,r=R,mid; 26 while(l<=r) 27 { 28 mid=l+r>>1; 29 if(sum[mid]-sum[L-1]<=sum[R]-sum[mid])l=mid+1;else r=mid-1; 30 } 31 return mid==R?mid-1:mid; 32 } 33 void sol(int l,int r,int *f) 34 { 35 if(l==r){f[0]=1;f[w[l]]=mod-1;return;} 36 int mid=gt(l,r); 37 int n=sum[r]-sum[l-1],nn=1; 38 while(nn<=2*n)nn<<=1; 39 int *a=new int[nn|5],*b=new int[nn|5]; 40 sol(l,mid,a);sol(mid+1,r,b); 41 ntt(nn,a,1);ntt(nn,b,1); 42 for(int i=0;i<nn;i++)a[i]=1ll*a[i]*b[i]%mod; 43 ntt(nn,a,-1); 44 for(int i=0;i<nn;i++)f[i]=a[i]; 45 } 46 int main() 47 { 48 scanf("%d",&n); 49 for(int i=1;i<=n;i++)scanf("%d",&w[i]); 50 sort(w+2,w+n+1); 51 for(int i=2;i<=n;i++)sum[i]=sum[i-1]+w[i]; 52 sol(2,n,f); 53 for(int i=0;i<=sum[n];i++)ans=(ans+1ll*f[i]*w[1]%mod*pw(w[1]+i,mod-2)%mod)%mod; 54 printf("%d\n",ans); 55 return 0; 56 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=20,mod=998244353; 4 int n,Q,S,d[N],id[N],a[N],b[N],mn[1<<18|5],sz[1<<18|5],mx[1<<18|5]; 5 vector<int>g[N]; 6 int pw(int a,int b){int r=1;for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)r=1ll*r*a%mod;return r;} 7 void dfs(int x,int p,int msk) 8 { 9 if(msk>>(x-1)&1){a[x]=b[x]=0;return;} 10 int sa=0,sb=0; 11 for(int i=0;i<g[x].size();i++)if(g[x][i]!=p)dfs(g[x][i],x,msk),sa=(sa+a[g[x][i]])%mod,sb=(sb+b[g[x][i]])%mod; 12 int c=pw(1+mod-1ll*sa*id[x]%mod,mod-2); 13 a[x]=1ll*id[x]*c%mod;b[x]=1ll*(1+1ll*sb*id[x]%mod)*c%mod; 14 } 15 int main() 16 { 17 scanf("%d%d%d",&n,&Q,&S); 18 for(int i=1,u,v;i<n;i++){scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);d[u]++;d[v]++;} 19 for(int i=1;i<=n;i++)id[i]=pw(d[i],mod-2); 20 int nn=1<<n; 21 for(int i=0;i<nn;i++)sz[i]=sz[i>>1]^(i&1); 22 for(int i=0;i<nn;i++){dfs(S,0,i);mn[i]=1ll*(sz[i]?1:mod-1)*b[S]%mod;} 23 for(int i=0;i<nn;i++)mx[i]=mn[i]; 24 for(int i=0;i<n;i++)for(int j=0;j<nn;j++)if(!(j>>i&1))(mx[j|(1<<i)]+=mx[j])%=mod; 25 while(Q--) 26 { 27 int k,msk=0;scanf("%d",&k); 28 for(int i=0,x;i<k;i++)scanf("%d",&x),msk|=(1<<(x-1)); 29 printf("%d\n",mx[msk]); 30 } 31 return 0; 32 }