[考试反思]0306省选模拟39:延续

俩原题。对于看视频课太匆忙的我来说,还是算俩新题吧。

为啥感觉最近总是考第$9$啊。最近这种名次的频率好高。。

(好菜啊第$9$还学个啥呢啊脑子呢???这还翻个什么盘啊)

然而其实第$9$也是混来的。

最开始先看的$T1$发现好像是原题,但是印象不深,大概还记得第一步怎么做。

接着往后看,$T2$看起来像弱智题。$T3$的话又是原题,思路极其简单但是是$exSAM+LCT$写出来会暴毙。于是扔在最后。

然后回$T1$尝试回忆。然后就没有然后了。折腾来折腾去想了两个小时硬是没想到$dp$定义。

果断换题。然后一看$T2$,好像的确有点弱智啊。

思路大概是对的,但是在枚举三元环上卡了一下。然后就真的忘记了怎么$O(m \sqrt{m})$枚举三元环了。

然后的确就一直没有想起来。又耗了一个小时,最后利用大小点卡常数,理论上时间复杂度还是$O(n^2)$

但是实际上常数非常小,我自己貌似也构造出什么数据卡满我自己。然而时间也不多了,调着调着就交了。

最后剩了十几分钟给$T3$。尝试爆写$exSAM$最后还是放弃了。

我为啥又把暴跳父亲忘了???如果想起来的话这次就能有两道题都是$n^2$过$2 \times 10^5$了!

然而既然考场上没写。。。那考后就老老实实写正解吧。。。

强烈谴责RNB考后暴力暴跳父亲AC的无脸行为

话说我自己数据结构能力是真的弱啊

T1:gift

大意:两数列$a,b$。有些位置为空,问有多少种方案填数使之成为排列,满足通过至少$k$次交换$a$变成$b$。对所有$k \in [0,n-1]$求解。$n \le 2000$

如果序列已经填满了数,那么最少交换次数可以这么表示:所有$a_i \rightarrow b_i$连边。然后每个环需要交换$size-1$次。所以交换次数就是$n-$环个数。

现在有些位置为$0$了,那么所有的边分四类$0-x,x-y,x-0,0-0$。而有些边已经有公共点了($0$除外)。把它们缩成一条链

对于$x-y$这一类,我们发现在缩成链之后两端点都未消失,证明它们都只出现了一次。

我们可以把它们两个当成同一个数看待,可以发现这对最后的图没有影响,在最后的时候展开就行了。

所以边只剩下三类,我们分别讨论它们之间的关系:

我们发现,$0-x$这种边它的$x$一定只出现了一次,所以一定与$0$相连了,那么要么就是接上了一个$0-0$,要么就是接上了另一个$0-x$,或者说自己连上自己变成自环。

对于第一种情况,新的两个端点就是$0-0$了,那么相当于这条边变成$0-0$了,而同时$0-0$的总量加一减一后并没有改变。

对于第二种情况,那么就是合并成了一个新的$0-x$。对最后的环数答案并没有什么影响。

所以我们只在意$0-x$这一类边自己形成了多少个环,以及方案数。

直接算不好算,考虑容斥,得到$i$个环的方案数是$g_i =\sum\limits_{j=i}^{cnt_{0-x}} \binom{cnt_{0-x}}{j} \begin{bmatrix} j \\ i \end{bmatrix} (cnt_{0-0}+cnt_{0-x}-j)^{\underline{cnt_{0-x}-j}}$

意思就是说,枚举有多少条$0-x$边在环里,对于剩下的边,我们在$cnt_{0-0}$个$0-0$边和$cnt_{0-x}$个$0-x$边中任意选择一条接在后面。方案数是下降幂。

后面乱选的部分也有可能形成环,所以这个$g$是至少的形式。用一个简单的二项式反演就能得到恰好的形式。

对于所有的$x-0$边,同理。它和$0-x$边如果要产生关系,一定要借助$0-0$而上面的第一种情况说了只要用到$0-0$就会变成$0-0$所以只需要考虑$x-0$与自身以及$0-0$的关系。

这两部分像个背包。直接$OGF$卷起来就好了。得到的是把所有的$0-x$边以及$x-0$边连成环或者变味$0-0$的方案数了。

所以现在只需要继续考虑$cnt_{0-0}$条$0-0$边就好了。

这个的方案数比较好算,环的形状一共是第二类斯特林数种,然后你再给它们赋予$cnt_{0,0}$的先后顺序,也就是个阶乘。

一起卷起来就得到答案了。

$Dy$讲的时候真实啥也没听懂,自己回放的时候其实也不明白,说啥都没有自己做一遍有效。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod 998244353
 4 int mo(int a){return a>=mod?a-mod:a;}
 5 #define S 2002
 6 int n,a[S],b[S],al[S],c00,c01,c10,cir,in[S],out[S],C[S][S],s[S][S],A[S][S],G[S],g[S],H[S],h[S],f[S],ans[S];
 7 int main(){
 8     scanf("%d",&n);
 9     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
10     for(int i=1;i<=n;++i)scanf("%d",&b[i]);
11     for(int i=1;i<=n;++i)in[i]=out[i]=-1;
12     for(int i=1;i<=n;++i)out[a[i]]=b[i],in[b[i]]=a[i];
13     for(int i=1;i<=n;++i)if(in[i]==-1&&out[i]!=-1){
14         int p=i;al[p]=1;
15         while(p&&out[p]!=-1)p=out[p],al[p]=1;
16         if(!p)c10++;
17     }
18     for(int i=1;i<=n;++i)if(in[i]==0){
19         int p=i;al[p]=1;
20         while(p&&out[p]!=-1)p=out[p],al[p]=1;
21         if(!p)c00++;else c01++;
22     }
23     for(int i=1;i<=n;++i)c00+=a[i]==0&&b[i]==0;
24     for(int i=1;i<=n;++i)if(in[i]>0&&out[i]>0&&!al[i]){
25         int p=i;cir++;
26         while(!al[p])al[p]=1,p=out[p];
27     }
28     for(int i=0;i<=n;++i)for(int j=C[i][0]=1;j<=i;++j)C[i][j]=mo(C[i-1][j-1]+C[i-1][j]);
29     for(int i=s[0][0]=1;i<=n;++i)for(int j=1;j<=i;++j)s[i][j]=(s[i-1][j-1]+s[i-1][j]*(i-1ll))%mod;
30     for(int i=0;i<=n;++i)for(int j=A[i][0]=1;j<=i;++j)A[i][j]=A[i][j-1]*(i+1ll-j)%mod;
31     for(int i=0;i<=c01;++i)for(int j=i;j<=c01;++j)g[i]=(g[i]+1ll*C[c01][j]*s[j][i]%mod*A[c01+c00-j][c01-j])%mod;
32     for(int i=0;i<=c01;++i)for(int j=i;j<=c01;++j)G[i]=(G[i]+(j-i&1?mod-1ll:1ll)*g[j]%mod*C[j][i])%mod;
33     for(int i=0;i<=c10;++i)for(int j=i;j<=c10;++j)h[i]=(h[i]+1ll*C[c10][j]*s[j][i]%mod*A[c10+c00-j][c10-j])%mod;
34     for(int i=0;i<=c10;++i)for(int j=i;j<=c10;++j)H[i]=(H[i]+(j-i&1?mod-1ll:1ll)*h[j]%mod*C[j][i])%mod;
35     for(int i=0;i<=c01;++i)for(int j=0;j<=c10;++j)f[i+j]=(f[i+j]+1ll*G[i]*H[j])%mod;
36     for(int i=0;i<=c01+c10;++i)for(int j=0;j<=c00;++j)ans[i+j]=(ans[i+j]+1ll*f[i]*s[c00][j]%mod*A[c00][c00])%mod;
37     for(int i=0;i<n;++i)printf("%d ",n>=i+cir?ans[n-i-cir]:0);
38 }

T2:girls

大意:$[0,n)$。定义合法三元组为三者之间均无连边且$i<j<k$。贡献为$Ai+Bj+Ck$。求总贡献。$n,m \le 2\times 10^5$

这题也就是经典的容斥了,全部情况加起来减去至少有一条边加上至少有两条边再去掉三元环

别的都好说,三元环的问题大概就是按照度数排序那一套复杂度$O(m^{1.5})$

做法也就是把所有的点按照度数排序之后,度数小的向度数大的连边。

对于点$i$枚举所有出边打标记,再枚举一次出边$j$,再枚举$j$的儿子$k$。若$k$有标记则是三元环。

联赛前做过,现在忘掉了,每个三元环只在度数最小的点初被枚举,具体复杂度证明忘记了,感性理解一下吧。

考场上思维僵化只会严格按照$\sqrt{n}$为阈值分大小点了,然而一小点两大点的情况不能很好地统计,于是又退化成$O(n^2)$了。

但是不难发现这样做的常数很小很小。所以$O(n^2)$过$200000$没什么大问题。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define S 200005
 4 #define ull unsigned long long
 5 ull A,B,C,ans,tot[S],deg[S]; int n,m;
 6 vector<int>v[S],in[S],vs[S],vb[S],inb[S],Bi;
 7 unordered_map<int,bool>M[S];
 8 ull cal(int x){return x*(x-1ull)>>1;}
 9 int main(){
10     cin>>n>>m>>A>>B>>C; int sq=sqrt(m);
11     for(int i=0,a,b;i<m;++i){
12         scanf("%d%d",&a,&b);
13         if(a>b)swap(a,b); deg[a]++; deg[b]++; M[a][b]=M[b][a]=1;
14         v[a].push_back(b); in[b].push_back(a); tot[a]+=b;
15         ans-=cal(a)*A+a*(a*B+b*C) + (cal(b)-cal(a+1))*B+(b-a-1)*(a*A+b*C) + (cal(n)-cal(b+1))*C+(n-b-1)*(a*A+b*B);
16     }
17     for(int i=0;i<n;++i)sort(v[i].begin(),v[i].end()),sort(in[i].begin(),in[i].end());
18     for(int i=0;i<n;++i)ans+=i*(cal(n-1-i)*A+B*i*(n-1-i)+C*cal(i));
19     for(int i=0;i<n;++i){
20         ull x=0,cnt=0;
21         for(auto j:v[i])ans+=i*cnt*A+x*B+j*cnt*C,x+=j,cnt++;
22     }
23     for(int i=0;i<n;++i){
24         ull x=0,cnt=0;
25         for(auto j:in[i])ans+=i*cnt*C+x*A+j*cnt*B,x+=j,cnt++;
26     }
27     for(int i=0;i<n;++i)for(auto j:v[i])ans+=v[j].size()*(i*A+j*B)+tot[j]*C;
28
29     for(int i=0;i<n;++i)for(auto j:v[i])if(deg[j]>=sq)vb[i].push_back(j);else vs[i].push_back(j);
30     for(int i=0;i<n;++i)for(auto j:in[i])if(deg[j]>=sq)inb[i].push_back(j);
31     for(int i=0;i<n;++i)if(deg[i]>=sq&&vb[i].size()>1)for(auto j:vb[i])for(auto k:vb[j])if(M[i][j]&&M[j][k]&&M[i][k])ans-=i*A+j*B+k*C;
32     for(int i=0;i<n;++i)if(deg[i]<sq&&vs[i].size()>1)for(auto j:vs[i])for(auto k:vs[j])if(M[i][j]&&M[j][k]&&M[i][k])ans-=i*A+j*B+k*C;
33     for(int i=0;i<n;++i)if(deg[i]<sq&&vs[i].size()>1)for(auto j:vs[i]){
34         for(auto k:vb[i])if(M[i][j]&&M[j][k]&&M[i][k])ans-=i*A+min(j,k)*B+max(j,k)*C;
35         for(auto k:inb[i])if(M[i][j]&&M[j][k]&&M[i][k])ans-=k*A+i*B+j*C;
36     }
37
38     for(int i=0;i<n;++i)if(deg[i]<sq){
39         for(auto j:inb[i])Bi.push_back(j);
40         for(auto j:vb[i])Bi.push_back(j);
41         for(int j=0;j<Bi.size();++j)for(int k=j+1;k<Bi.size();++k){
42             ull x=i,y=Bi[j],z=Bi[k];
43             if(x>z)swap(x,z);
44             if(x>y)swap(x,y);
45             if(M[x][y]&&M[x][z]&&M[y][z])ans-=A*x+B*y+C*z;
46         }Bi.clear();
47     }
48     cout<<ans<<endl;
49 }

T3:string

原题链接。题号12.

思路很简单,代码很难写。

干就是了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define S 888888
 4 int n,rt=1,pc=1,lst[22],c[11][S],len[S],ans,m,la,f[S],t,w[22][S],lz[22][S];char s[20000003];
 5 vector<int>v[22],P[22];
 6 struct LCT{
 7     int c[2][S],f[S],s[S];
 8     void down(int p){for(int i=1;i<=n;++i)if(lz[i][p])w[i][c[0][p]]+=lz[i][p],w[i][c[1][p]]+=lz[i][p],lz[i][c[0][p]]+=lz[i][p],lz[i][c[1][p]]+=lz[i][p],lz[i][p]=0;}
 9     bool nr(int p){return c[0][f[p]]==p||c[1][f[p]]==p;}
10     void spin(int p){
11         int F=f[p],G=f[F],d=c[1][F]==p,B=c[!d][p];
12         if(nr(F))c[c[1][G]==F][G]=p; c[!d][p]=F; c[d][F]=B;
13         f[f[f[B]=F]=p]=G;
14     }
15     void splay(int p){
16         int F=p,t=0; while(nr(F))s[++t]=F,F=f[F]; s[++t]=F; while(t)down(s[t--]);
17         for(;F=f[p],nr(p);spin(p))if(nr(F))spin(c[1][f[F]]==F^c[1][F]==p?p:F);
18     }
19     void access(int p){for(int r=0,s=p;s;s=f[r=s])splay(s),c[1][s]=r;splay(p);}
20     void link(int a,int b){splay(a);f[a]=b;}
21     void cut(int p){access(p);f[c[0][p]]=0;c[0][p]=0;}
22 }T;
23 void add(int p,int op){T.access(p);for(int i=1;i<=n;++i)lz[i][p]+=op*w[i][p];}
24 void Fa(int p,int fa){T.link(p,fa);add(p,1);f[p]=fa;}
25 void extend(int I,int C){
26     int p=lst[I],np,q,nq;
27     if(q=c[C][p]){
28         if(len[q]==len[p]+1){lst[I]=q;T.access(q);lz[I][q]++;w[I][q]++;return;}
29         nq=++pc; len[nq]=len[p]+1; for(int i=0;i<10;++i)c[i][nq]=c[i][q];
30         w[I][nq]++;
31         Fa(nq,f[q]); add(q,-1); T.cut(q); Fa(q,nq);
32         for(;c[C][p]==q;p=f[p])c[C][p]=nq; lst[I]=nq;
33     }else{
34         lst[I]=np=++pc; len[np]=len[p]+1; w[I][np]=1;
35         for(;p&&!c[C][p];p=f[p])c[C][p]=np;
36         if(!p){Fa(np,1);ans+=len[np]-len[f[np]];return;}
37         if(len[q=c[C][p]]==len[p]+1){Fa(np,q);ans+=len[np]-len[f[np]];return;}
38         nq=++pc; len[nq]=len[p]+1; for(int i=0;i<10;++i)c[i][nq]=c[i][q];
39         Fa(nq,f[q]); Fa(np,nq); add(q,-1); T.cut(q); Fa(q,nq);
40         for(;c[C][p]==q;p=f[p])c[C][p]=nq; ans+=len[np]-len[f[np]];
41     }
42 }
43 int main(){//freopen("string1.in","r",stdin);
44     scanf("%d%d",&n,&t);
45     for(int i=1;i<=n;++i){
46         scanf("%s",s);lst[i]=1;
47         for(int j=0;s[j];++j)extend(i,s[j]-48);
48         v[i].push_back(0);P[i].push_back(lst[i]);
49     }scanf("%d",&m);
50     for(int i=1;i<=m;++i){
51         int op,x,y,z;scanf("%d",&op);
52         if(op==1){
53             scanf("%d%d",&x,&y);
54             if(t)y^=la,y%=10;
55             extend(x,y);
56             v[x].push_back(i);P[x].push_back(lst[x]);
57         }if(op==2){
58             scanf("%d%d%d",&x,&y,&z);
59             int p=P[x][upper_bound(v[x].begin(),v[x].end(),y)-1-v[x].begin()];
60             T.splay(p);printf("%d\n",la=w[z][p]);
61         }if(op==3)printf("%d\n",ans);
62         if(op==4){
63             int p=1;la=0;scanf("%s",s);
64             for(int j=0;s[j];++j)p=c[s[j]-48][p];
65             if(p){T.splay(p);for(int j=1;j<=n;++j)la=max(la,w[j][p]);}
66             printf("%d\n",la);
67         }
68     }
69 }

没有调到暴毙还是非常开心的,写的时间比调的时间长。

原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/12431632.html

时间: 2024-10-04 17:02:48

[考试反思]0306省选模拟39:延续的相关文章

[考试反思]0113省选模拟6:过载

真累啊...离上次放假也挺久,离下次放假也挺久,离上次放出去玩也挺久,离下次放出去玩还不知道有多久... 好累啊...大脑基本成天在挂机了.什么也不想干了... 持续状态不佳.但是今天运气好,所以考试排名看起来还可以. T1没认真读题也没看数据范围,以为是送分题,17分钟写完交了...然后我就把分送出去了 像个弱智一样...但是现在的精神状态的确不太能支持好好做题 幸亏T2是个比较简单的SAM+dp,思维量不大,脑子宕机的时候也能写一写. (归功于当时给大家讲课时稍微有一点理解,要是其它的板子我

[考试反思]0114省选模拟7:迷离

这次考得相对不错,但是没什么水准. 只不过记得T1这道原题而已.虽说我忘了怎么做,而且数据范围不一样...差不多是从头想的. 但是并没有AC,像个弱智一样,有两个细节写的完全不对还有80分运气也是真好. 其实挂了不止两个细节...以为是原题于是上来就写20分钟写完,然后过一会出一个锅... 然后看T2,感觉$O(nk^2)$也许差不多?常数很大...但也不会别的.挺好想但是不是很好写. 于是乎强烈谴责cbx没素质暴力水题考后还不改正解的无脸行径 于是就开始写,写了一个半小时. 看T3,绝对大神题

[考试反思]0117省选模拟10:争夺

T3出了一点锅,于是按IOI赛制打的. 可能也是这辈子唯一一次好好打的IOI赛制了. 提答,又沉里面了,进去就出不来.莫名的虚荣让我根本没有回头看传统题. 于是的确在T3的80%时间里一直单题rk1,然而其实很慌,剩下两道题又怎样? 运气好,T1特别水,T2数据水,T3用奇技淫巧多拿7分于是并列rk1了. 数组没清空丢了1分... 状态差的不行,一下午一道题都没改出来...咕到第二天也没改出来 于是在第二天考试的时候写完三个暴力之后终于把T2A了... 然后第二天考试就炸了,没什么好说的 T1:

[考试反思]0130省选模拟13:悔恨

0+30+20=50.rk8 关键在于: T1写错个变量名挂了100分 kxkxkxkx(激动的语无伦次) 考试过程?上来看T1,一个比较裸的基环树dp,断开环上一条边之后大概就是一个稍加改动的最大独立集. 思路不难想,细节倒是有一点,考场上调啊调啊过了样例又手模了各种数据都过了两个半小时之后很开心就扔了. 然后看T2/3啥都不会,写了俩随机化就走了. 然而T3随机化+贪心是可以AC的.正确性不知道...没写... 最后还有5分钟回T1,突然发现T1可以不是基环树而是基环树森林??? 啊修锅修锅

[考试反思]0410省选模拟67:迷惑

现在想想,先做$T3$真乃人间迷惑行为. 部分分不多的一场考试,$T1$部分分最多结果没花时间光荣爆零,结果正解真的就是一个暴力+大力分类讨论 $T2$也比较可想,然而看着$75pts$的子任务心中有几分慌张,苟了个暴力跑路了. 结果一个弱智$T3$的$10pts$部分分$O(n^8)$暴写了$2.8k$.从这代码长度看是不是$10pts$您施舍的有点少啊. 其余部分分一点用没有,不知道咋想的. T1:链 大意:维护操作:加边,询问有几个点满足:删掉之后图中剩下的都是若干链.$n,m \le 2

[考试反思]1219省选模拟3: 释怀

有些东西渐渐就远去了...不必挂念. 只有时间才拥有如此力量.我们能做的,唯有释怀. 这次的题格外顺手,大概是我的强项了. 但是考得还是不够好吧...感觉可以更高的 今天迎来了学了OI一年多比较重要的一个成就:(虽说是在考后) AC1000道题!还是挺不容易的. 第1000道题是今天的T3.大部分是自己思考的,题也不是很简单,挺好的. 挺过了联赛,现在想要等到下一次整百,可能就要到3月份了. 我还能在OI多久呢? 回到这场考试. T1的数据范围只有10000,让我想起了ALO那道题50000数据

[考试反思]0110省选模拟5:信仰

又倒一啦 10分真是个熟悉的成绩(虽然没有爆零熟悉) 状态一直低迷,没什么好说的 答题策略的话...就那样吧 一眼看出T1是结论题,没有部分分,不好写. 但T2是伯努利数的差不多是模板题了,于是就奔着它去了. 没有注意$0^0=1$.过不去样例最后交的暴力 没有抽时间认真打T3的暴力,因为至多30分. 因为现在30分和0分对我来说是一样的.我是要靠着省选翻盘,拿大众分的话肯定还是退役,求个稳,4个月白学. 现在的答题策略的确不能像联赛时一样了.现在求稳是赢不了了,在稳住200和争取230里我可能

[考试反思]0122省选模拟12:延迟

博客咕过了一年我也就忘了我考试状态了2333. T1是弱智题但是没想...写个暴力跑路了(时间不够,主要投在T2/3上了) 然而其实想到了一个乱搞,觉得能得分的概率不大,结果数据奇水完全不对的玩意还有20分,然而我并没有写... 然而T2写的是正解,虽说没有其他人的状压优秀,T了一个细节WA了一个拿了80分,凑合吧. 然后T3时间不多的时候写的,拿个暴力,想到了正解大概怎么写但是没有写,太恶心. 考后改题写了写,一下午就过去了...一晚上也就过去了...弄得跟我颓废了半天一样... 然而是真xx

[考试反思]0207省选模拟20:风波

估分10+20+20=50.T1没炸T2炸了.总体来说炸得不算厉害. 开考的第一个小时一直在争论T1到底是不是原题. 管它是不是我按照原题的方法打呗(其实不太一样,更简单了但是数据范围加大时限减小) 一个LCT调了好久...至少最后还是调出来了,难得...(第一次在考场上调出LCT...虽说原来考场上也没写过) T2特别简单但是看错题导致想到正解又放弃了而且写了错误题意下的暴力光荣爆零(样例就是个x啊) T3的话是个单变量的题,惯性打表找规律,没有发现什么,但是根据函数增长速度隐约觉得答案是个低