PKUWC2018 5/6

总结:

D1T1T2的思路较为好想,D1T3考试时估计是战略放弃的对象,D2T1思路容易卡在优化状态上(虽然明显3n的状态中有很多无用状态,从而想到子集最优,选择子集最优容易发现反例,从而考虑连带周边一起考虑,去年考场上想出来的,今年却想不出来***)但50十分容易,D2T2的式子超出目前水平(多项式的式子推法需要继续加强),D2T3在学过MinMax容斥以及树上高斯消元(好像还需要FWT)后较为简单,目前水平在250-380中来回飘荡,感觉pkuwc2019要完。

loj#2537. 「PKUWC2018」Minimax

 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 }
View Code

loj#2538. 「PKUWC2018」Slay the Spire

 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 }
View Code

loj#2540. 「PKUWC2018」随机算法

 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 }
View Code

loj#2541. 「PKUWC2018」猎人杀

 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 }
View Code

loj#2542. 「PKUWC2018」随机游走

 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 }
View Code

 

posted @ 2019-01-03 14:24  leoiter  阅读(250)  评论(0编辑  收藏  举报