Codeforces Round 921 (Div. 1) 题解
Hello Ad-Hoc Forces!
A
字符集为前 \(k\) 个小写字母,给定长度为 \(m\) 的字符串,求所有的长度为 \(n\) 的字符串是否是这个字符串的子串。(此处字串不连续)
如果不是需要给出反例。
\(1\le n,k\le 26\),\(1\le m\le 1000\)。
\(\sum n,\sum m\le 10^6\)
sol.
D1A 就是神秘贪心,汗流浃背了吧。
如果是连续字串直接暴力枚举所有的字符串即可!
但是不连续,怎么办呢?
因为不连续肯定每个字符尽量取后面的肯定更容易找出来反例。
显然如果直接往后面取没有意义,因为前面可能还有相同字母。
这样正解就呼之欲出了——每次贪心的选取之后第一次出现最后面的字母。
如果能取完 \(n\) 个就是有解的,否则无解。
预处理倒着开个桶找每个位置往后每个字母第一次出现的位置,然后正着做一次。
\(O((n+m)k)\)
https://codeforces.com/contest/1924/submission/244479375
B
有一条长度为 \(n\) 的数轴,每个位置依次编号为 \(1\sim n\)。上面有 \(m\) 个关键点 \(x_i\),第 \(i\) 个关键点有权值 \(v_i\)。保证 \(1,n\) 是关键点。
一个位置 \(p\) 的代价是它左侧最近的关键点的权值乘它到它右侧最近的关键点的距离。若 \(p\) 是一个关键点则其代价为 \(0\)。
\(q\) 次询问。
1 x v
在点 \(x\) 处添加一个权值为 \(v\) 的关键点,保证之前 \(x\) 不是关键点。2 l r
查询区间 \([l,r]\) 的代价和。
\(n,m,q\leq 3\times 10^5,v\leq 10^7,x\leq n\)。
sol
Trash problem。
用 set
维护关键点的位置,每次放置关键点之后只有这个点左右两边的两段会影响到。
转化成区间赋等差数列,区间求和。
线段树秒了。
\(O((n+q)\log n)\)
https://codeforces.com/contest/1924/submission/244480959
C
有一张正方形的纸,定义一次操作为将它的 \(4\) 个尖角向内折至中心,容易发现这样折之后仍然是一个正方形。
每次给定 \(N\),将一张纸不断重复折 \(N\) 次后展开,记 \(M\) 为所有凸折痕的长度和,\(V\) 为所有凹折痕的长度和。
记\(\dfrac{M}{V}=a+b\sqrt 2\),\(a,b\in \Q\),求 \(b\) 对 \(999999893\) 取模的值。
多测,\(n\le 10^9\),\(T\le 10^4\)
sol
Ad-Hoc 能不能 414!!111
首先你可以拿一张纸折着玩玩,或者和我一样用几何画板玩玩。
然后你会发现从第二次开始,每次凹折痕和凸折痕都是一样长的!
其实从第二次折痕开始,每次折的时候都折了正反交错的偶数层,所以每次凹折痕和凸的折痕都是一样长的。
考虑到每次边长是原来的 \(\dfrac{\sqrt{2}}{2}\) 倍,层数是 \(2\) 倍,长度就是上次的 \(\sqrt{2}\) 倍。
求比值不用关心绝对大小,不妨设初始正方形边长为 \(1\)(或者你可以设边长为 \(4\) 然后只关心左上四分之一部分的折痕)。
因此 \(n=1\) 的时 \(M=0,V=\sqrt{2}\)。
\(n\ge 1\) 时
为了方便,你可以封装一个 \(a+b\sqrt{2}\) 的类。
\(O(T\log n\log P)\)
https://codeforces.com/contest/1924/submission/244505075
D
给定 \(n,m,k\),求有多少个由 \(n\) 个 (
,\(m\) 个 )
组成的序列满足最长的合法括号子序列的长度恰为 \(2k\),对 \(10^9+7\) 取模。
对 \(10^9+7\) 取模,\(n,m,k\leq 2000\)。
sol
神秘计数。
\(\min{n,m}\le k\) 肯定无解。
括号匹配考虑卡特兰数。
考虑 \((x,y)\) 代表前 \(x\) 个数字中左括号数量减去右括号数量为 \(y\),然后把所以的 \((x,y)\) 连成一条折线,起点为 \((0,0)\),终点为 \((n+m,n-m)\)。
考虑 \(k\) 个匹配的括号不难发现要求这条折线最低点为 \(k-m\)。
然后你发现这个东西不好算,我们可以设 \(f(t)\) 为最低点不高于 \(k-m\) 的方案数。答案就是 \(f(k-m)-f(k-m-1)\)。
考虑和 y=t 的最后一个交点翻一下,得到了 \((0,0)\) 到 \((n+m,2t-n+m)\) 的直线。方案数量为 \(\binom{n+m}{t+m}\)。
因此答案为 \(\binom{n+m}{k}-\binom{n+m}{k-1}\)。
\(O(T+n)\)
https://codeforces.com/contest/1924/submission/244491378
E
\(n\times m\) 的矩形纸片,每次均匀随机选择一条平行于坐标轴不是边缘线的线切开,保留左半边或者上半边,直到面积小于 \(k\)。
求期望次数,对 \(10^9+7\) 取模。
\(1\le n,m,\sum n,\sum m\le 10^6\),\(1\le k\le 10^{12}\)
sol
感觉非常 at,感觉是出题人玩原神导致的。
我会 \(O(n^2)\) DP!然而没什么用,不过鱼直接硬干干出来了,但是我不会生成函数&多项式。
考虑一个长度为 \(n+m-2\) 的排列,依次选择(如果不能裁就不能裁剪),然后拆开算每条边的贡献。
显然如果需要裁从上到下或者从左到右第 \(i\) 条边,那么显然这条边下面和右边的边都不能裁掉,需要在这条边之后。
然后你发现你还是没法做,因为你不知道裁这次前当前边的长度,导致你不知道另外一条边的范围是多少。
我们试着转换一下思路,我们假定裁完这条边之后 还能继续裁,也就是说我们先不考虑最后一次裁产生的贡献。
这样另外一边只需要小于 \(\lceil\dfrac{k}{i} \rceil\) 的边都应该在这条边之后出现就可以了。
记得最后答案加 \(1\)。
https://codeforces.com/contest/1924/submission/244773100
\(O(\sum (n+m) )\)
F
\(n\) 个人中有一个缺席。你需要在 \(\lceil\log_{1.116}n\rceil-1\) 次询问得到缺席的人在哪两个人中的。
每次询问选定 \([l,r]\),你可以知道 \([l,r]\) 中来的人数,但是每次询问得到的结果为 \(r-l+1\) 或者 \(r-l\),但是并不一定为真。
保证不存在连续的三个回答都是真或者都是假。
\(1\le n,\sum n\le 10^5\)
sol
*3500 神仙交互题
注意到 \(\sqrt[4]{1.5}\approx 1.106\) 这与 \(1.116\) 比较相近。
也就是说我们需要试着在 \(4\) 次询问中从 \(3\) 组中排除掉 \(1\) 组人。
然后我们大概就有了这样一个询问树。(显然左右对称)
注:
\(1,2\) 代表询问第 \(1,2\) 组,\(1,3\) 代表询问第 \(1,3\) 组,其余类推。
\(1\) 代表从询问得知其中有缺席,\(0\) 代表没有。
\(3\) x 代表排除了第 \(3\) 组。
但是问题在于,\(1.106<1.116\),多余的询问如何减少呢?
我们发现如果排除了第二组的情况会少很多,并且都是只用三次询问就排除的,所以我们考虑不均匀分组。
似乎可以用 DP 等方法计算最优解。
取三组分别为 \(36\%,28\%,36\%\) 即可通过。
https://codeforces.com/contest/1924/submission/245013194