就是说,永远不会博弈枯了枯了。
来写点一套题的题解吧(如果我会的话。
场A(-6)。
考虑染球个数的前缀和,会发现满足一些不等式: s i − s i − 1 ≥ 0 , s i − s i − 1 ≤ 1 , s r i − s l i − 1 ≥ k i , s n − ( s r i − s l i − 1 ) ≥ k i s_i-s_{i-1} \ge 0,s_i-s_{i-1} \le 1,s_{r_i}-s_{l_i-1} \ge k_i,s_{n}-(s_{r_i}-s_{l_i-1}) \ge k_i si−si−1≥0,si−si−1≤1,sri−sli−1≥ki,sn−(sri−sli−1)≥ki 。然后会发现有个s_n的东西弄不掉,我们就想办法把它变成常数。
发现可以二分 s n s_n sn ,于是它就变成常数了,并且要满足 s n − s 0 = m i d s_n-s_0=mid sn−s0=mid ,然后就是差分约束,跑个 spfa \text{spfa} spfa 即可。
效率: O ( n m log n ) O(nm\log n) O(nmlogn) 。
要剪枝,不然会T。
场A(-4)。
F ( ) F() F() 相当于求两个数写成二进制形式下的 lcp \text{lcp} lcp 。
显然,对于 ( i , j ) (i,j) (i,j) 且 i < j i
因此,我们其实只需要考虑对于 i − 1 i-1 i−1 和 i i i 区间,要满足 F ( a i − 1 , r i − 1 ) ≥ F ( a i , r i − 1 ) , F ( a i − 1 , l i ) ≤ F ( a i , l i ) F(a_{i-1},r_{i-1}) \ge F(a_i,r_{i-1}),F(a_{i-1},l_i) \le F(a_i,l_i) F(ai−1,ri−1)≥F(ai,ri−1),F(ai−1,li)≤F(ai,li) 。
因此我们考虑 dp \text{dp} dp : f i f_i fi 表示以 i i i 为结尾的答案,那么对于 i i i ,能够转移到它的点一定是一段区间,而且 i i i 越大,区间只会往左移。因此记个前缀和就好了。
效率: O ( m 2 m ) O(m2^m) O(m2m) 。
注意模数是 1 e 8 + 7 1e8+7 1e8+7 …
场未A。
模拟,题目太长,没时间打。
场未A,乍一眼看应该是计算几何,不会。
场A(-4)。
考虑如果知道了最后一个串怎么求答案。那就只要看颜色最多的数量是否达到总长的一半即可,如果没达到就是总长,否则就是去掉最多颜色数的两倍。
因此我们其实只要知道每个颜色在最后一个串出现多少次即可,那其实也就是要知道每个操作为 1 1 1 的串对于最后一个串的贡献。
因此做个 dp \text{dp} dp 即可。 f i f_i fi 表示第 i i i 个串在最后一个串中出现多少次,然后把它传递给那两个合并串即可。
效率: O ( n l o g n ) O(nlogn) O(nlogn) 。
场上需要写 fread \text{fread} fread 才能过…大受震撼。
场1A。
直接 6 ! 6! 6! 判断就好了。
效率: O ( 6 ! × l e n g t h ) O(6!\times length) O(6!×length) 。
场未A。以下口胡。
是我不会的 nim-k \text{nim-k} nim-k 游戏了。
如果二进制下,每一位 1 1 1 的个数都是 k + 1 k+1 k+1 的倍数(这题是 3 3 3 的倍数),那么先手必败,否则必胜。
因此, A
如果选择了一些 set \text{set} set ,那么这些 set \text{set} set 里的石堆可以看成向量 a i a_i ai , B
要移除一些石堆来确保自己能赢,也就是说,每个 a i a_i ai 最后会剩下 0 / 1 / 2 0/1/2 0/1/2 堆,那其实 B
要做的就是在模 3 3 3 意义下,使得 ∑ k i a i = 0 \sum k_i a_i=0 ∑kiai=0 。
因此, A
要选的就是 a i a_i ai 的最大权线性无关组。用线性基维护,这里的线性基是对 3 3 3 取模的。具体就是每次到非零位,如果当前位的值比自己小,那就交换并且消高位往下走即可。
然后听说模 3 3 3 很慢,要用 4 4 4 进制来优化常数。
场未A,以下口胡。
最优解只可能在 T = 1 T=1 T=1 和 T = T m a x T=T_{max} T=Tmax 取,因此做两遍就好了。
搞出一棵生成树,非树边最多 51 51 51 条。
考虑如果只走树边,那么就考虑在i点的答案为 g i g_i gi ,然后我们维护一个堆,按照 g i + c i g_i+c_i gi+ci 从小到大排序,然后每次用堆顶去更新别的点答案。
假设堆顶为 i i i ,那么我们要更新的点 j j j 要满足树上 dis ( i , j ) ≤ f i \text{dis}(i,j) \le f_i dis(i,j)≤fi 且还没有被更新过。因此我们考虑建出点分树,从i往上走,对于每个点分中心维护一个队列,按照 dis \text{dis} dis 排序,因此我们每次更新队列中的前面一部分的点即可。
现在考虑非树边,如果经过了非树边 ( u , v ) (u,v) (u,v) ,那么一定会经过 u u u 点,那么我们最多有 51 51 51 个这样的点,因此现在原图上跑 51 51 51 次单源最短路。然后在原本的基础上考虑如果 i i i 要更新到 j j j 并且走了非树边,那么我们就枚举关键点,那么能够更新那个 j j j 的要求就是 d i s ( i , u ) + d i s ( u , j ) ≤ f i dis(i,u)+dis(u,j) \le f_i dis(i,u)+dis(u,j)≤fi ,因此也维护一个队列即可。
打标记使得每个点只进入堆一次,那么效率就是 O ( n l o g n + 51 n ) O(nlogn+51n) O(nlogn+51n) 。
场A(-1)。
先判掉一些非法情况,比如 h i ! = 0 , h n ! = n − 1 , h i > h i + 1 h_i!=0,h_n!=n-1,h_i>h_{i+1} hi!=0,hn!=n−1,hi>hi+1。
然后我们设前i的答案为 f i f_i fi 。
如果 h i > h i − 1 h_i>h_{i-1} hi>hi−1 的话,那么第 i i i 个数肯定是前 i i i 个数中的最大值或者最小值,因此 f i = f i − 1 × 2 f_i=f_{i-1}\times 2 fi=fi−1×2 。
如果 h i = h i − 1 h_i=h_{i-1} hi=hi−1 的话,那第 i i i 个数就是选择了最大值和最小值中的一个数,因此我们再维护最大值和最小值中还有多少数没有被选择即可。
效率: O ( n ) O(n) O(n) 。
-1是因为 ( s + = f i ) % = P (s+=f_i)\%=P (s+=fi)%=P 写成了 % P \%P %P …枯了枯了。
场1A。
n < 6 n<6 n<6 无解,否则 n n n 是奇数就是 3 , n − 3 3,n-3 3,n−3 ,偶数就是 2 , n − 2 2,n-2 2,n−2 。
场1A。
有生之年我没有被卡精度。
兔子重量的比例不会变,所以每次增加的重量不会变,所以直接加上 k × w i s k \times \frac{w_i}{s} k×swi 即可。
场1A。
发现 B = 793999 B=793999 B=793999 和 P = 1 e 9 + 7 P=1e9+7 P=1e9+7 没有被卡过,以后都用这个。
求出每次加入一个数之后,新的串前缀的 hash \text{hash} hash 值即可。
效率: O ( n 2 ) O(n^2) O(n2) 。
原本想写 trie \text{trie} trie 树,但是感觉要用 map \text{map} map 存下一个节点就是 n 2 l o g n^2log n2log 的了,于是还是 hash \text{hash} hash 吧。
All in all,打得其实还不错,但是要注意一些细节的东西,而且其实长的题目也不一定就是很难的题目,所以还是最好把题目全读一遍更好。