2022.04.04省选模拟赛总结

1.时间安排

7:20~7:50 看题面

T1:图论题,n=2000有70分的高分,感觉很可做。

T2:字符串dp,可能要AC自动机,已经很久没写了。

T3:好像见过原题?

7:50~8:20

确定没读错题后,直接写线段树优化建图的拓扑排序,简单调试一下,需要spj的题大样例居然和标准答案一模一样,就懒得写spj了,直接写前面的题。

8:20~10:00

T1被第二个样例坑大惨了……

一开始想了个 n * m 的搜索,但是样例调不对,发现理解错题意了,浪费半个小时。

想着先写个2^m*m的暴力起码先拿点分,写完又是调了好久,终于把题面样例过了。

但是,下发文件的样例输入不合法……

接着去测下发文件的样例,发现是0。

画出图后,发现答案确实应该是14,就一直在找代码的问题。

一直调到10点都没结果,放弃了。

10:00~11:00

上来又把题意读错了,又浪费20分钟写了错的代码。

仔细分析后把30分dp写出来了。

已经忘了AC自动机怎么写了,就放弃了。

11:00~11:40

继续刚T1,这时候冷静下来看了看样例。

"一共8个点,存在8->9的边,图还不连通?"

当场感觉白白浪费了2个小时,不过及时止损至少还有30分……

又把前面n*m的代码翻了出来,加了map套set判重,虽然大样例答案对了,但是根本跑不动……

匆匆检查低级错误提交。

result:

T1:30 T2:30 T3:100

2.反思

T1:

时间全浪费在错误的下发样例了……

但是点双边双的题目很久没做了,就算有时间也不一定能写出来。

T2:

AC自动机也已经忘完了啊(之前总结里的毒奶成功了……),复习了一下后70分很快就写出来了。

正解的广义矩乘也不难,主要问题还是在AC自动机不熟练上。

T3:

3.简要题解

T1:

一句话题意:给出一张n点m边的无向连通图,求所有的只被一个简单环包含的边的编号异或和。

\(n,m\leq 1e6\)

求出所有的点双连通分量。

考虑一个点双连通分量里面的边都被至少一个环包含,当且仅当边数大于等于点数(显然)。但如果边数大于点数,所有的边都会被至少两个环包含。

所以只需要统计有哪些点双的边数等于点数,这些点双里面的边就是要求的边。

在学姐的提醒下,我才发现的代码里有一个致命的细节没注意到,被三角形的菊花hack掉(TLE)。

统计答案时,我的做法是暴力枚举点双内部的点,然后枚举所有与它相连的边,看到达的点是否在同一个点双内。

但是如果是三角形菊花数据,就会因为割点存在于每个点双内部,导致的大量冗余枚举而TLE掉。

正确做法:tarjan求点双,最后加入vector的一定是割点,不枚举这个割点就好了。

这种做法学姐证明了一定是小于等于O((n+m)logm)的,而且根本跑不满。

三角形菊花生成代码如下:

int n=66667,m=99999;
printf("%d %d\n",n,m);
for(int i=2;i<=n;i+=2){
	printf("%d %d\n",i,i+1);
	printf("1 %d\n",i);
	printf("1 %d\n",i+1);
}

T2:

一句话题意:给出m个字符串,每个字符串有一个价值,生成一个长度为n的字符串,价值为m的字符串在n中出现的次数 * 字符串的价值之和,最大化价值。

\(n\leq 1e12,\sum_{i=1}^{m}|s_i|\leq 200\)

70分直接上AC自动机,转移到对应的fail指针即可。

100分的话需要广义矩阵乘法,支持如下运算:

\[f_{n,k}=max_i{f_{n-1,i}+val_{i,k}} \]

可以先预处理出来转移矩阵,然后就可以对答案矩阵快速幂了。

T3:

原题链接

4.总结

1.复习

不能再拖了,tarjan,AC自动机这些都要抓紧复习了。

最近列个计划表吧,有空就找几道题复习复习。

2.stl的空间

订题的时候第一遍提交MLE了,检查一遍发现是std::vector爆空间了。

64位系统下常用stl的初始空间(即使是空的):

(单位:字节)
vector: 24
set: 48
map:48
(c++11)unordered_map:56

stl不管储存元素是什么类型的,初始空间都是这么大,所以不能豪爽地直接开1e6甚至1e7个的stl,小心空间。

posted @ 2022-04-04 13:14  Displace  阅读(25)  评论(0)    收藏  举报