废话
将昨天的坑填了一下~
很不幸,今天早上等待我们的依然是模拟赛qaq
更伤心的是,部分可怜的人提交上去的代码给不小心删掉了,导致最后这些人不知道分数。
而我和ZZY,恰好就撞了进这群人中。(5555555555555
感觉今天的题目简单了一丢丢,第一题应该能AC,无奈只有样例做测试,于是最后并不知道对错。。。
第二题应该能水一点分吧。。漏掉一点细节,导致思路错掉了。。。
第三题是真的厉害,全场最高分30,而我连暴力都不会打。
进入正题
还是吧今天的模拟赛题目记录一下,学到了不少东西!
T1
【题目大意】
给你一个由小写字母组成的长度为n的字符串,要你从中选出一个子序列,满足以下两个条件,然后输出。
- 这个子序列包含了原字符串中所有出现过的字母,并且每个字母在子序列中恰好只出现一次
- 在满足条件1的同时,使得其字典序最小
【样例输入】
zzyyaoaknoi
【样例输出】
zyaknoi
【数据规模】
1 ≤ n ≤ 1 0 6 1 \leq n \leq 10^6 1≤n≤106
【题解】
题解的做法很优秀,一看就是对的。(但我的就不知道是不是对的了qwq
搞一个栈。
对于当前的字母,假如栈里面已经有它了,那么就跳过。
否则,如果这个字母在后面已经没有出现了,那么就放入栈中。(因为每种字母一定要出现一次)
再否则,如果这个字母比栈顶的字母的字典序要小,并且栈顶字母在后面还有出现,那么将栈顶弹出,重复这个操作直到不满足条件为止,然后将这个字母压入栈中。
最后将栈输出即可。
可以发现这个栈的维护过程,其实是在让字典序小的字母尽可能在前面,字典序大的丢到后面去,这样我们就可以得到答案了。
T2
【题目大意】
现在你在聊天对话框中输入了一个表情,你可以进行三种操作:
- 将所有表情复制到剪贴板
- 粘贴
- 删去一个表情
设函数 f ( x ) f(x) f(x)表示至少需要 f ( x ) f(x) f(x)次操作才能恰好得到x个表情。
如 f ( 1 ) = 0 , f ( 4 ) = 4 , f ( 6 ) = 5 f(1)=0,f(4)=4,f(6)=5 f(1)=0,f(4)=4,f(6)=5。
现在输入一个n,需要你求ans%998244353的值。
其中 a n s = ∑ i = 1 n f ( i ) ∗ 1926081 7 n − i ans=\sum_{i=1}^n f(i)*19260817^{n-i} ans=∑i=1nf(i)∗19260817n−i
【样例输入】
10
【样例输出】
224985019
【样例解释】
f f f函数的值分别为: 0 , 2 , 3 , 4 , 5 , 5 , 7 , 6 , 6 , 7 0,2,3,4,5,5,7,6,6,7 0,2,3,4,5,5,7,6,6,7
【数据规模】
1 ≤ n ≤ 2 × 1 0 6 1 \leq n \leq 2 \times 10^6 1≤n≤2×106
【题解】
ans求解的那个主要的问题还是在于 f f f函数,所以重点依然是求解 f f f函数。
对于每个数字 x x x,我们可以向 x ∗ 2 x*2 x∗2连一条长度为 2 2 2的边,向 x ∗ 3 x*3 x∗3连一条长度为 3 3 3的边,……,向 x ∗ i x*i x∗i连一条长度为 i i i的边,然后 x x x再向 x − 1 x-1 x−1连一条边即可。最后从数字1开始跑一次最短路即可得到答案。
显然边太多了,做点优化。
发现当 i i i为合数的时候这条边不会产生贡献,于是只连 i i i为质数时的边。
证明:对于合数,我们可以将它质因数分解,按照分解出来的质因子来连边得到的答案显然是更优的。
但是还不够,继续优化。
因为一些很玄学的原因,出题人在实践的时候发现当 i > 11 i>11 i>11的时候那些边也都是不会产生贡献的,于是不连那些边。
于是最后的做法就很优秀了。
T3
【题目大意】
有一个
n
∗
m
n*m
n∗m的矩阵,小a站在
(
1
,
1
)
(1,1)
(1,1),目的地是
(
n
,
m
)
(n,m)
(n,m),只会向上或向右走,中间k个矩形的障碍物,两条到达终点的路径是不同的只有满足某个障碍物在一条路径的左边而在另一条路径的右边
这个条件才成立。
现在问有多少条到达终点的不同路径。
输入格式:n,m,k,后面k行每行四个整数描述障碍物的两个顶点的坐标,进而体现出障碍物的位置。
【样例输入】
5 5 3
2 2 2 3
4 2 5 2
4 4 4 4
【样例输出】
3
【数据规模】
1
≤
n
≤
1
0
9
1 \leq n \leq 10^9
1≤n≤109
1
≤
m
≤
1
0
6
1 \leq m \leq 10^6
1≤m≤106
1
≤
k
≤
1
0
7
1 \leq k \leq 10^7
1≤k≤107
【题解】
因为这样是两种相同的方案:
所以考虑限制行走方式——贴着障碍物走。
统计答案方案数时,我们按一列一列扫过去,假如扫的时候遇到了一个矩形的左边界,就像这样(来自出题人的题解的图):
我们发现绿色部分的是可以往上走的,所以可以将他们的答案累加到上面去。不要忘记,这里还要将撞到障碍物的部分的答案清零。
这样扫一遍就可以得到答案了。这个一列的答案可以用线段树来维护。
因为只有扫到矩形的左边界的时候才会有操作,于是将矩形的左边界排序一下过一遍就好了。
今天下午题目讲的比较好,出题人没有那么嗨,听的很明白,但是这个题目的背景。。(青春猪头少年不会梦到兔女郎学姐233)
但是照例还是老师先讲了算法,这次讲了网络流和费用流,网络流算法讲了ISAP算法(某LJY的癖好丫),跟dinic挺相似,但是比dinic快。老师讲得很好,大体听明白了,但是个人觉得讲的不是很好的方面是数组的定义不是很清楚,一开始的时候一笔带过,没听清楚,导致后面看代码比较懵逼。。(好在思路是很清晰的
dinic算法是跑完多次增广路之后再重新编号,而ISAP是递推的时候顺便就把编号改了,所以会快。
今天也就讲了板子,并没有做过多的应用以及网络流模型的构建技巧,所以也没什么好记的。(毕竟网络流也不是没学过。
我已经做好每天一场模拟赛的觉悟了。