9月做题记录
9月做题记录
✩ trick
✯ 会大部分,要\(tj\)提示
✬ 会小部分/完全没想到,看了\(tj\)才会
◈ 脑电波
✡ 有某一算法的神秘通用性质
⊗ 待补
- 9月做题记录
- ARC146C
- ARC146D
- CF1994G ✯
- P3599 Koishi Loves Construction ✬
- AGC030C
- AGC035C ✯
- AT_hitachi2020_e Odd Sum Rectangles ✬
- CF1267H Help BerLine ✬
- CF1270E ✯✩
- ARC148D mod M Game ✬
- P4484 [BJWC2018] 最长上升子序列
- P6970 [NEERC2016] Game on Graph
- AGC002E Candy Piles ✯✩
- CF1411F/CF1464D The Thorny Path ✩
- ARC180E LIS and Inversion ✯✩
- [ARC159C] Permutation Addition ✯
- [ARC159E] Difference Sum Query
- [ARC159F] Good Division ✯
- [AGC007E] Shik and Travel
- P10880 [JRKSJ R9] 莫队的 1.5 近似构造
- P10882 [JRKSJ R9] ZYPRESSEN ✬✩
- CF2019C Cards Partition
- CF2019D Speedbreaker
- CF2019E Tree Pruning
- CF2018D/CF2019F Max Plus Min Plus Size ✯
- CF2018E1/E2 Complex Segments ✯✩
ARC146C
显然只要所有大小为奇数的子集的异或和都互不相同即可
那么\(dp[i]\)表示长度为\(i\)的答案,考虑加入一个新的数\(a\),那么\(a\)只需要不与所有大小为奇数的子集的异或和相同即可,而又因为原本的那些就已经互不相同了,所以\(dp[i+1]=dp[i]\times(2^N-2^{i-1})\)
然后注意这样求出的\(dp[i]\)是有序集合,那么真正的答案就是\(\sum\frac{dp[i]}{i!}\)
这种求2-sat字典序最小解的做法按理来说是\(O(NM)\)的,但是似乎并卡不满啥的,总之能过
ARC146D
- 做法1
限制转换为\(A_{P_i}\leq X_i\)当且仅当\(A_{Q_i}\leq Y_i\)、\(A_{P_i}\geq X_i\)当且仅当\(A_{Q_i}\geq Y_i\)
这样就可以\(2-sat\)了,然后尽量让每个\(A\)取到最小即可
- 做法2 ✯
是官方\(tj\)的做法
把限制转换为\(A_{P_i}\leq X_i\)当且仅当\(A_{Q_i}\leq Y_i\)、\(A_{P_i}<X_i\)当且仅当\(A_{Q_i}<Y_i\)
然后先把所有值都赋为\(1\),然后一步步的调整即可
复杂度\(O(N+K)\)
CF1994G ✯
Hint真的蚌埠住:
- Think of the most stupid solution you can do
- Do memorization and some cuts
- Done!
考虑\(x\)在第\(i\)位取\(0/1\),会导致贡献\(2^i\times(k_i/n-k_i)\),其中\(k_i\)表示这\(n\)个数中第\(i\)位为\(1\)的数的数量
发现这样小的位会影响到大的位,但大的位不会影响小的位,所以 the most stupid solution
就是从到大递归,设状态\((i,sum)\)表示后\(i\)位的贡献和除以\(2^i\)的值
然后发现,因为\(sum\leq n\),所以总的状态数就只有\(O(NK)\)的,所以就可以过了
P3599 Koishi Loves Construction ✬
感觉除了打表找规律找出正解来,很难单独凭人类智慧直接推测出来啊
- \(X=1\)的情况
此时即要求不存在区间\([l,r](l>1)\)使得区间和同余\(0\),那么一定有\(a_1=n\)
如果\(n\)为大于\(1\)的奇数,此时有\(1+2+...+n-1\equiv 0\mod n\),即不合法
所以\(n\)只能为\(1\)或偶数
打表找规律可得:\(a_i=[i\%2==0]i-1/[i\%2==1]n+1-i\)
此时对于\(a_i\)序列在模\(n\)下等价于\(\{0,1,-2,3,-4...\}\),那么\(sum_i=\{0,1,-1,2,-2...\}\)显然合法
- \(X=2\)的情况
此时要求不存在区间\([l,r](l>1)\)使得区间积同余\(1\)且不存在\(pord_i\equiv0(i<n)\),那么一定有\(a_n=n\),\(a_1=1\),可以发现,如果\(n\)不是质数/\(1\)/\(4\),那么一定能用\(<n\)的不同数拼出\(n\),即\(prod_i\equiv0(i<n)\)一定会成立
所以\(n\)一定是质数或\(1\)或\(4\)
\(n=1/4\)特判一下
通过打表找规律又可得:\(pred_i\equiv i\mod n\),那么\(a_i\equiv\frac i{i-1}\mod n\),如果\(a_i=a_j\)即有\(\frac i{i-1}\equiv \frac j{j-1}\mod n\),化简得到\(i\equiv j\)显然在\(i\neq j\)时不成立
AGC030C
若\(K\leq 500\),那么直接让\(n=K\),然后第\(i\)层全部等于\(i\)即可
否则当\(K>500\)时,发现同一行全部相等的模型不适用了,因为如果替换第\(i\)行中的任意一个,都会导致与这一个相邻的两个\(i\)与其他的\(i\)的数量不同
考虑变成斜着的形式
123456
234561
345612
456123
561234
612345
发现这样构造后,相同的数之间就互不影响了,那么这时加入一个新的数\(7\)进来,只需要任意替换掉某一个数的一半为\(6\),且替换掉的位置不是在斜线上相邻的即可
eg:
123456
274561
345612
456127
561234
612745
这样最多能塞\(2N\)个数,发现\(K\)的最大值刚好是\(2\times 500\),那么这样构造就是合法的
AGC035C ✯
\(i\)与\(i+n\)间的路径的异或和为\(i\),即\(i\)与\(i+n\)之间的点(不包括\(i\)和\(i+n\))的异或和为\(i\)
首先,如果\(lowbit(n)=n\),那么一定无解,因为不可能找出数来凑出\(n\)
然后发现有个很好的性质,如果\(i\)是偶数,那么\(i\ xor1=i+1\),那么此时可以连边\((i,1)\),\((i+1,1)\),\((i+n,i+1)\),\((i+1+n,i)\)
如果\(n\)是奇数,现在就只剩下\(1+n\)没连了,此时随意找一个偶数\(i\),连边\((1+n,i+n/i+1+n)\)即可
如果\(n\)是偶数,\(1+n\)还是按照这种方式连,此时还有\(n\)和\(n+n\)没连,考虑用\(lowbit(n)\)和\(n-lowbit(n)\)来凑出\(n\),期望是构成路径\(n\rightarrow lowbit(n)\rightarrow n-lowbit(n)\rightarrow n+n\),但是显然\(lowbit(n)\)要到\(n-lowbit(n)\)必定经过一个\(1\),那么也就是说,实际的路径是\(n\rightarrow lowbit(n)\rightarrow \rightarrow n-lowbit(n)\rightarrow n+n\),发现任意两个\(<n\)间的点间,\(1\)是不可避免的,那么换个思路,把\(n\rightarrow lowbit(n)\rightarrow n-lowbit(n)\rightarrow n+n\)中的\(lowbit(n)\)替换成\(lowbit(n)\ xor1\rightarrow 1\),那么路径就变成了\(n\rightarrow lowbit(n)\ xor1\rightarrow 1\rightarrow n-lowbit(n)\rightarrow n+n\),即连边\((n,lowbit(n)\ xor1)\),\((n-lowbit(n),n+n)\)即可
复杂度\(O(N)\)
AT_hitachi2020_e Odd Sum Rectangles ✬
非常牛的题
要求尽量多的矩阵内的数之和为奇数,因为只在意奇偶性,那么换成异或和
不失一般性的假设\(N\leq M\)
先求出\(sum[i][j]\)表示矩阵\((1,1,i,j)\)的异或和,那么矩阵\((a,b,x,y)\)的异或和即为\(sum[x][y]\ xor\ sum[a-1][y]\ xor\ sum[x][b-1]\ xor\ sum[a-1][b-1]\),那么对于\(sum[i][j]\)的\(2^n\times2^m\)的矩阵(包含\(i=0/j=0\)),即要求这个矩阵的四个角的异或和为\(1\)且\(a<x\),\(b<y\)
考虑先确定\(a\)和\(x\)即先确定行,一共有\(C_{2^N}^2\)行,再来考虑选的列\(b\)和\(y\),因为要求四个角的异或和为\(1\),所以我们把所有列分成两类,一类是对应列中\(a\)行和\(b\)行值不同的,有\(k\)个,另一类是值相同的,有\(2^M-k\)个,那么显然,合法的矩阵的两个列必须是不同类型的列,所以列的方案数总共就是\(k(2^M-k)\leq 2^{2M-2}\),当且仅当\(k=2^M-k\)时等号成立,也就意味着,答案的上界在每两行间,对应的值不同的列的数量恰好为\(2^{M-1}\)时取到
考虑构造这个上界对应的\(sum[i][j]\),\(sum[0][j]\)和\(sum[i][0]\)都是\(0\),其余的,满足每两行间对应的值不同的列数恰好为\(2^{M-1}\)
因为已经\(sum[0][j]\)的值,且总的行数是\(2^M\)的,所以考虑倍增构造
如果已经知道\(0\sim2^i-1\)的构造方法,考虑构造\(2^i\sim2^{i+1}-1\),先把\(0\sim2^i-1\)的\(copy\)给\(2^i\sim2^{i+1}-1\),当然直接\(copy\)过后肯定不合法,此时再给\(2^i\sim2^{i+1}-1\)中含有\(2^i\)的列的值异或上\(1\),就可以了
证明:
- 对于\(x\in[0,2^i-1]\)和\(y\in[0,2^i-1]\),因为已经是合法构造了,且后面的操作没有再改变它们,所以第\(x\)行和第\(y\)行是合法的
- 对于\(x\in[2^i,2^{i+1}-1]\)和\(y\in[2^i,2^{i+1}-1]\),因为\(x-2^i\)和\(y-2^i\)是合法的,且它们分别取自\(x-2^i\)和\(y-2^i\),虽然有变换,但是\(x\)和\(y\)变换的列是相同的,所以合法
- 对于\(x\in[2^i,2^{i+1}-1]\)和\(y\in[0,2^i-1]\),\(x-2^i\)和\(y\)是合法的,而\(x\)是在\(x-2^i\)的基础上改变了有\(2^i\)的列
考虑研究任意两行\(a\)和\(b\)的差别,考虑从第一个\(2^{i+1}-1\geq a,b\)的\(i\)开始回溯操作,如果当前回溯中,\(a\)和\(b\)都在被新加入的那一侧,那么它们的差别等价于\(a-2^i\)和\(b-2^i\)的差别,那么现在考虑在\(2^{j+1}-1\geq a',b'\)的\(j\),此时不失一般性的假设\(a'\)是已经有的一侧,\(b'\)在新加入的一侧,那么\(a'\)和\(b'\)的变化就是\(a'\)和\(b'-2^j\)的差别,再算上那些含\(2^j\)的列,那么总结下来,任意两行\(a\)和\(b\)的差别可以用一个集合\(S\)表示(\(S\)g中存的二进制的位),如果当前列\(k\)有\(S\)中的奇数个元素,那么\(a\)和\(b\)这一位不同
因为可以知道,二进制中所有位是独立的,所以\(a\)和\(b\)当前列不同的概率就是\(\frac12\),那么也就是刚好一半的列不同,复合我们的限制
再回到原问题,现在知道了\(x-2^i\)和\(y\)的差别集合\(S\),那么在\(x-2^i\)的基础上变化了含有\(2^i\)的列后,因为二进制中所有位独立,所以会有\(\frac12\)原本\(x-2^i\)和\(y\)不同的列改变,此时变成了相同的,有\(\frac12\)原本\(x-2^i\)和\(y\)相同的列被改变,此时变成了不同的,那么总共\(x\)和\(y\)依旧还是有一半的列不同,此时\(x\)和\(y\)的差别集合就是\(S\bigcup\{i\}\)
复杂度\(O(2^{N+M})\)
CF1267H Help BerLine ✬
首先,可以通过惊人的注意力注意到\(\log_{\frac32}8500=23\),不过这只是后面要用到的方案的一步证明,所以感觉就算注意到了就没啥\(p\)用,况且除了\(bot\)真有人类能注意到吗
总之这个\(24\)是一个\(\log\)级别的东西,所以考虑缩小问题规模,也就是考虑递归子问题
先考虑只染一种颜色,那么一定有任意时刻这种颜色的点都不能相邻,发现如果把染了这种颜色的点去掉后,把其他点单独提出来,变成一个新的序列,如果这个序列也是合法的,那么加上原本那些染了色的点进去依旧合法
那么考虑怎么染色,肯定想尽量多的染色,有一个比较朴素的想法,让操作从后往前,每次考虑当前操作的点有没有被标记,如果没有,给它染色并标记当前与它相邻的点
发现这样至少可以染\(\lceil\frac n3\rceil\)个点,即剩下\(\lfloor\frac23n\rfloor\)个点,那么也就意味着需要有\(n\times {\frac23}^K<1\),也就是说颜色数量\(K\)至少是\(\log_{\frac32}8500\)级别的
那么就这样一直递归子问题即可
复杂度\(O(NK\log N)\)
CF1270E ✯✩
在网格图上无敌的黑白染色...!
真没想到这也能染,太牛了
- 第一种是纯粹的黑白染色
首先根据一个点\((x,y)\)的\(x+y\)的奇偶性把点染成黑白两色,然后如果两种颜色的点都存在,那么可以就这样分配
否则如果只存在\(x+y\)为偶数的点,那么把点变成\((\frac{x+y}2,\frac{x-y}2)\),可以证明两点间的距离变成了原来的\(\frac1{\sqrt2}\)倍,好像说这是啥旋转,感觉像是顺时针转了\(135\)度然后顺带压缩了一下
如果是奇数,可平移一位
那么一直转,直到出现不同色的点为止,然后可以发现,因为每次任意两点间距离会变成原来的\(\frac1{\sqrt2}\)倍,而一个原本不是原点永远不会变成原点,所以旋转次数是\(O(\log V^2)\)的,也就是\(O(\log V)\)的
- 另一种做法,就是直接分别考虑\(x\)和\(y\)的奇偶性,然后分成四类,然后大力分讨即可,感觉没上种方便(
ARC148D mod M Game ✬
考虑最后只剩两个点\(x\)和\(y\)没被选择时,设\(Alice\)取的数之和为\(A\),\(Bob\)的为\(B\),那么必须满足\(A+x\equiv B+y\)以及\(A+y\equiv B+x\),那么一定有\(2x\equiv 2y\),e那么有\(x\equiv y\)或\(x\equiv y+\frac m2\)(\(m\)是偶数)
考虑\(x\equiv y\)的\(x\)和\(y\)匹配,\(x\equiv y+\frac m2\)(\(m\)是偶数)的\(x\)和\(y\)匹配,那么如果最后所有点都匹配上了且匹配的\(x\equiv y+\frac m2\)是偶数对,那么\(Bob\)显然必胜
如果有点没匹配上,那么显然\(Alice\)可以通过操作使得不匹配点的最后一步不满足\(2x\equiv 2y\),那么\(Alice\)必胜
P4484 [BJWC2018] 最长上升子序列
首先肯定不能是逐个在序列的末尾添加数的这种求法,显然状态数爆表
考虑从小到大的添加数字,如果把当前数放到\(i\)和\(i+1\)之间,设\(dp[i]\)表示以\(i\)为结尾的最长上升子序列,那么\(dp'[j]=dp[j-1](j>i+1)\),\(dp'[j]=dp[j](j\leq i)\),\(dp'[j]=\sum_{k\in[1,i]} dp[k]+1(j=i+1)\),那么考虑记前缀最大值数组\(f[i]\),发现\(f[i-1]\leq f[i]\leq f[i-1]+1\),所以改为记录差分数组\(g[i]\)表示\(f[i]-f[i-1]\),那么这个\(g[i]\)就是一个\(01\)数组,而每次插入到\(i\)和\(i+1\)之间的话,就是插入一个\(1\)到\(i\)和\(i+1\)之间,然后原本的\(i+1\)后面的第一个\(1\)变成\(0\)
复杂度\(O(2^NN^2)\),但肯定跑不满的,但依旧不太能过,所以需要打个表(
P6970 [NEERC2016] Game on Graph
称希望平局的是\(0\),不希望平局的是\(1\)
给每个点两个状态,一个是\(0\)先手,一个是\(1\)先手,那么显然,如果有边\((x,y)\),那么会有\((x0,y1)\),\((x1,y0)\),即把一个点拆成两个,分别表示两个状态
然后先考虑判能否平局,有两种方式
- 判平局
先缩点,变成\(DAG\)图,然后考虑最底层的点,如果是一个\(size\geq 2\)的点,那么这个点中的所有点都是平局,然后考虑往上推,如果一个\(0\)点存在出边指向一个平局状态的点,a那么这个\(0\)点为平局状态,如果一个\(1\)点所有指向的点均为平局状态点,那么这个\(1\)点是平局状态
除此之外,还有一些比较复杂的情况,比如偶环之类的,总之要大力分讨一下
然后就可以这样一直类似染色的方式染上去即可,然后对于不是平局的点,就普通的博弈做法即可
- 判不平局
这种做法要好写一些
对于一个出度为\(0\)的点,其是不平局的,然后给它标记上,那么对于一个\(0\)点,如果它所有的出边都指向非平局点,那么它是平局点,如果一个\(1\)点存在非平局点的出边,那么就是非平局点
这个也是类似染色的就染上去就行了,判断具体是谁胜依旧普通的博弈做法
\(luogu\)的第一篇题解的写法比较妙,如果是比较普通的写法的话,注意不能标记和胜负同时标记,因为这样无法保证\(x\)一定比\(x\)的某个出边更早加入队列中
复杂度\(O(N)\)
AGC002E Candy Piles ✯✩
每次要么全部\(-1\),要么删最大的,可以发现,只要当前最大的不被删,那么一直都是最大的
考虑网格图,将\(a_i\)从大到小排序,然后放网格图上,全部\(-1\)就是向上走一步,删最大就是向右走一步,边界上是必输,那么就推回来其他点的状态
发现斜线上的点的状态相同,那么求出原点斜出去接近边界的那个点的状态即可
复杂度\(O(N\log N)\),瓶颈在排序
CF1411F/CF1464D The Thorny Path ✩
可恶喵!导数还在追我!
显然答案为\(\prod sz_i\),\(sz_i\)为第\(i\)个置换环的大小
通过打表可以发现,最优的情况是尽量使得分到的每一个\(sz\)都为\(3\),具体的,有:
- \(n\%3==0\),\(sz_i=3\)
- \(n\%3==1\),要么有两个\(sz_i=2\),其余为\(3\),要么有一个\(sz_i=4\),其余为\(3\)
- \(n\%3==2\),只有一个\(sz_i\)为\(2\),其余为\(3\)
具体证明:
显然\(sz_i=2/4\)都是不得已的折中策略,那么只需证明\(sz_i=3\)是最优策略即可
由高维不等式\(\prod a_i\leq(\frac{\sum a_i}m)^m\)可知,当\(a_i\)尽量平均时能取最值,设这个平均的值为\(x\),即\(x=a_i=\frac nm\),设\(\sum a_i=n\)
那么有求\(f(x)=x^{\frac nx}\)的最大值,考虑它的单调性,因为\(n\)是常数,无影响,去掉,现在来考虑\(g(x)=x^{\frac 1x}\)的单调性
\[g(x)=x^{\frac 1x}=e^{\frac{\ln x}x}\\ g'(x)=e^{\frac{\ln x}x}\frac{1-\ln x}{x^2} \]显然\(x=e\)时取得最大值,但又要求\(x\)是整数,所以考虑\(g(2)\)和\(g(3)\)的大小,发现\(g(3)>g(2)\),所以\(x\)取\(3\)时最优
那么显然一个环\(i\)能一次操作拆分成\(a\)和\(sz_i-a\)两个部分,而两个环\(i\)和\(j\)能一次操作合并成\(sz_i+sz_j\)的大环
对于\(n\%3==0\)的情况,只需要先将所有\(sz_i>3\)的部分拆了,然后现在剩下了一下\(sz_i=1\)和\(sz_i=2\)的部分,优先\(1\)和\(2\)匹配,剩下的再随便弄一下就行
对于\(n\%3==1\)的情况,如果是有两个\(sz_i=2\)的情况,先拆\(sz_i>3\)的部分,然后先用剩下的\(sz_i=1/2\)的拼出两个\(2\),然后再去凑\(3\)即可;如果是一个\(sz_i=4\)的情况,可以先去枚举是那个环拆出\(4\)的部分,然后剩下的就用\(n\%3==0\)的做法去做即可
对于\(n\%3==2\)的情况,依旧先拆所有\(sz_i>3\)的部分,然后先用剩下的\(sz_i=1/2\)的拼出一个\(2\),然后再去凑\(3\)即可
ARC180E LIS and Inversion ✯✩
这种题一般都是先从代价/价值最小/最大一点点转移到其他情况
首先考虑要求代价为\(0\)的最长序列,那么直接设计\(dp\)状态,\(dp[i][j]\)表示前\(i\)个数中,以前\(i\)个中第\(j\)小为结尾的最长序列长度
那么有转移:
设\(f[i][j]=\max_{k=1}^j dp[i][k]\),则转移变成:
显然有\(f[i][j]\leq f[i][j-1]+1\),直接交换\(dp[i][j]\)的序列中的\(j\)和\(j-1\)即可得证
那么现在找出差分数组\(g[i][j]=f[i][j]-f[i][j-1]\),则\(g[i][j]\)是一个\(0/1\)序列
稍微模拟一下即可发现,\(g[i]\rightarrow g[i+1]\),就是在\(0/1\)序列的开头加上一个\(1\),并删去后\(a_i\)个数中最考前的\(1\),没有就不删,最终的答案就是\(g[n]\)中\(1\)的个数
那么每增加一个代价,就是可以少一个这样的删去\(1\)的操作,来考虑转换这个操作
发现只关心最终序列中的\(1\)的个数,那么操作等价于,给你一个\(n\)的全是\(1\)的数组,将\(a_i\)从小到大排序,每次取出数组中最小的为\(1\)的位置,如果这个位置\(\leq a_i\),就删去\(1\),否则不操作,令可以删到\(1\)的\(a_i\)的\(i\)为有标记的\(i\)
发现这样做,\(a_i\)的顺序就不重要了,而且显然,每次删除操作的时候,只需要删去最大的\(a_i\)即可,且一直直到删到一个有标记的\(i\),此时序列的长度\(+1\)
复杂度\(O(N\log N)\),瓶颈在排序,其余操作都是\(O(N)\)的
[ARC159C] Permutation Addition ✯
显然最后的序列中,每个\(a_i\)都是序列的平均值,即\(a_i=\frac{sum}n\),而每次\(sum\)都会加上\(\frac{n(n+1)}2\),设\(sum_0\)表示初始的\(sum\)
分类一下,当\(n\)为奇数的时候,\(\frac{n(n+1)}2\)是\(n\)的倍数,那么就要求\(sum_0\)为\(n\)的倍数
当\(n\)为偶数的时候,\(k\times\frac{n(n+1)}2\)是\(\frac n2\)的倍数,那么加两次就是\(n\)的倍数了,当\(sum_0\)是\(n\)的倍数时,就直接操作,是\(\frac n2\)的倍数时,先随便操作一次变成\(n\)的倍数,然后再看怎么弄
首先有一个很好用的策略,就是每次加上\(1,2,3,...,n\),再来一次\(n,n-1,...,1\),那么任意两个数间的差值都不变,且发现这样一次性操作两次的话,无论\(n\)是奇数还是偶数,都能让\(sum\)加上的数为\(n\)的倍数,那么就能适中保持当前的\(sum\)是\(n\)的倍数了
猜测应该会存在策略使得满足上述条件即可构造出合法的方案,显然应该会需要根据当前的\(\frac{sum}n\)来调整策略,找到最大和最小的数\(a\)和\(b\),我们依旧希望保留上面那个一次性操作两次的结构,因为\(a\)是最大的,\(b\)是最小的,所以一定是希望让\(a\)相对其他数\(-1\),\(b\)相对其它数\(+1\),那么假设\(a\)就是第一个数,\(b\)是第二个数,则原本是操作\(1,2,3,...,n\),\(n,n-1,...,1\),即\(n+1,n+1,...n+1\),现在换一下,变成操作\(1,2,3,...,n\),\(n-1,n,...,1\),即\(n,n+2,...,n+1\),那么就实现了我们的目标
操作次数:\(O(NV)\),题目给的\(1e4\)绰绰有余
[ARC159E] Difference Sum Query
比较抽象的题目,题面翻译的有点让人误会啊,原题面在\(l=m+1\)和让\(t+1\)间写的是句号,翻译的写的逗号,一开始一直以为是只有\(l=m+1\)才能让\(t+1\)
首先把题面关于\(m\)的式子转换一下,令\(c_i=\frac{a_i}{b_i}\)
因为题目说了,\(c_i\in[\frac 12,2]\),所以\(\frac{c_{t\mod M}}{1+c_{t\mod M}}\in[\frac 13,\frac 23]\)
考虑\(m=l+\lfloor(r-l)\times \frac{c_{t\mod M}}{1+c_{t\mod M}}\rfloor\)的意义,就是取\([l,r]\)的\([\frac 13,\frac 23]\)点
考虑感觉这个过程建树,每个数的节点就是当前的\(m\),左右孩子就是左区间的\(m\)和右区间的\(m\),显然树最多只有\(\log_{\frac 32}N\)层,也就是\(85.183\)的范围,大概就是\(1e2\)的数量级,发现这样的话,因为询问是\(1e4\)级别的,那么每次循环跑个从根到某一个点,这样的复杂度显然是可以接受的
考虑怎么求答案,先建出\([c,d]\)的虚树,这里把所有被经过的点和边都要加入,无论是否是属于\([c,d]\)的,发现这个树显然是满足其中序遍历出来的序列就是原系列,那么\(c\)就是最左边的那个点,\(d\)就是最右边的那个点,且相邻两点在树上高度差即为\(x_j\)和\(x_{j+1}\)的差,又因为询问的都是相邻的点,显然相邻的点第一次被分离开时是其中一个被选中了,也就是说,相邻两点一定是呈祖先关系的,那么这个相邻两点在树上的高度差也即相邻两点在树上的路径长度,即它们之间边的数量,模拟一下可以发现,虚树上每条边都会被经过两次,除了\(c\)到根的路径上的边和\(d\)到的路径上的边
那么只需要计算出总的边数,以及\(c\)到根的边数和\(d\)到根的边数
那么根、\(c\)和\(d\)具体在哪都是好求的,\(O(1e2)\)就可求出,考虑怎么求总的边数
因为一共有\(d-c+1\)个点,所以至少有\(d-c\)条边,发现剩下的没被算到边的数量就等同于虚树上的不出与\([d,c]\)间的点,又因为中序遍历的性质,这些不在区间中的点一定是在\(c\rightarrow\)根和\(d\rightarrow\)根上的
复杂度\(O(1e2Q)\)
[ARC159F] Good Division ✯
线性做法 ✡
首先,好的序列满足以下两个限制:
- 长度为偶数
- 没有绝对众数
考虑证明,若存在某一个数\(x\)的出现次数\(cnt_x\)恰好是序列的一半,那么显然可以一直删\(x\)和一个不是\(x\)的数来把序列删空,对于不存在这样的\(x\)的序列,只需要进行一些调整使得出现\(x\)即可
设\(dp[i]\)表示前\(i\)个的答案,那么\(dp\)转移有:
\(check(i,j)\)是在判断\([i,j]\)内是否有绝对众数
显然有值的\(dp[i]\)只能是偶数的\(i\),所以后面那个判断\(i-j+1\&1=0\)的其实可以省去,下文就省略不管了
考虑优化转移,记录\(pre_i\)表示\(\sum_{j\leq i}dp[j]\),那么\(dp[i]=pre_{i-1}-s\),这里\(s\)记录的就是不合法的\(dp[j]\)的和
考虑怎么把\(s\)从\(i-2\)转移到\(i\),\(s\)会加上那些以\(i-2\)为右端点不合法且以\(i\)为右端点合法的值,减去以\(i-2\)为右端点合法以\(i\)为右端点不合法的点
- 以\(i-2\)为右端点不合法且以\(i\)为右端点合法
假设这个区间是\([l,i]\),那么显然有\([l,i-2]\)有一个恰好数量为\(\frac{i-2-l+1}2+1\)的数\(x\),且\(a_{i-1}\)和\(a_i\)都不是\(x\)
- 以\(i-2\)为右端点合法以\(i\)为右端点不合法
假设这个区间是\([l,i]\),可以知道,肯定是\(a_{i-1}\)和\(a_i\)导致了某个数的数量超过了\(\frac{i-l+1}2\),又因为在\([l,i-2]\)是合法的,也就是说在\([l,i-2]\)中是\(\leq\frac{i-2-l+1}2\)的,那么只能是在\([l,i-2]\)中有\(\frac{i-2-l+1}2\)个,且这个\(x\)有\(x=a_{i-1}=a_i\)
发现上面两个都满足,要么是\([l,i]\)有、要么是\([l,i-2]\)有一个\(x\)满足其数量恰好是区间长度的一半,这是一个很强的限制,考虑它的限制:
发现对于同一个\(x\),如果区间\([l,i]\)中有一半是\(x\),\([l',i]\)有一半是\(x\),那么显然有\([l,l'-1]\)中有一半是\(x\),即对同一个\(x\),这样一半的区间可以拆成不包含的关系,进而可以连边,即\(i\rightarrow l\),其中\([l+1,i]\)满足有一半是\(x\)的最大的\(l\),这样会变成一种类似树状的结构,也就是会使转移变得十分有序
如果这样的边的数量允许的话,似乎我们只需要找到每个\(x\)的这种边,然后转移的时候直接转移即可,大概就是给每个点记录一个\(f[v]\)表示颜色为\(v\)的以\(i\)为右端点的这种有一半是\(x\)的区间的左端点-1的那个点的\(dp\)值之和,对于\(i\)的\(f[v]\)就从\(i\)的\(l\)转移过来即可
考虑边的数量
结论是,对于每种\(x\),作为这种区间的左/右界的端点的数量是\(O(cnt_x)\)的,而显然我们的边的数量大概就是这种作为边界的点数量
考虑这样一种方法,把序列中所有为\(x\)的位置都标记为\(1\),然后对于所有为\(1\)的\(i\),把\([i,i+1]\)加入队列中,每次取出左端点最小的区间\([l,r]\),如果这个区间和队列中的区间\([x,y]\)有交,变\([l,r+y-x+1]\)塞回队列,并删除\([l,r]\)和\([x,y]\),如果不存在,那么把\([l,r]\)放到另一个维护的队列中(注意到,实际上不是左端点最小的区间一定是某一个\([i,i+1]\),所以这种做法说起来很高大尚的样子,其实也就是每次变成\([l,r+2]\)罢了)
正反都做一次,可以得到所有可作为这种区间的左/右界的端点以及每个\(i\)对应的\(l\)(上文提到建边用的),显然点数是\(O(cnt_x)\)的
复杂度的话,精细点可以\(O(N)\),一般点就\(O(N\log N)\)
\(cdq\)分治的双\(log\)做法 ✩
依旧还是绝对众数的限制:
首先,好的序列满足以下两个限制:
- 长度为偶数
- 没有绝对众数
考虑证明,若存在某一个数\(x\)的出现次数\(cnt_x\)恰好是序列的一半,那么显然可以一直删\(x\)和一个不是\(x\)的数来把序列删空,对于不存在这样的\(x\)的序列,只需要进行一些调整使得出现\(x\)即可
那么现在考虑\(cdq\)分治来维护\(dp\)
对于当前区间,\([l,mid]\),\([mid+1,r]\),先递归出\([l,mid]\)的\(dp\)值,求出\([l,mid]\)的后缀绝对众数,\([mid+1,r]\)的前缀绝对众数,然后对于一个长度为\(len\)的区间,后缀的绝对众数的种数是\(\log len\)级别的
而对于一个跨\(mid\)的区间\([a,b]\)的绝对众数,一定是\([a,mid]\)或\([mid+1,b]\)的绝对众数,也就意味着,所有跨\(mid\)的区间的绝对众数是\(\log N\)级别,就可以枚举所有可能众数,算出后缀中该众数\(x\)的数量与前缀中的数量,对于一个区间\([mid-t1+1,mid+t2]\),其中\([mid-t1+1,mid]\)的\(x\)的数量为\(v1\),\([mid+1,mid+t2]\)的数量为\(v2\),那么有\(2\times(v1+v2)>t1+t2\),即\(2\times v1-t1>t2-2\times v2\),要么树状数组直接求了,要么用\(unordered\_map\)记录一下,然后给前后缀排个序,就可以双指针了,另一种方法是用摩尔投票,如果当前数是\(x\)就\(+1\),不是就\(-1\),然后前后缀相加大于\(1\)的合法,本质和上面那个一样
复杂度\(O(N\log^2N)\)或\(O(N\log^3N)\)
[AGC007E] Shik and Travel
感觉确实简单啊,咋是黑的呢
显然要二分\(lim\)然后\(check\),那么只需要具体考虑怎么\(check\)了
题目要求每条边都要经过两次,即进入一棵子树后,必须把子树内的点遍历完了再出来,其实就是一个类\(dfs\)的过程
很自然的想到\(dp\),设\(dp[u][a][b]\)表示\(u\)子树内,进去的那条链的长度为\(a\),出来的为\(b\),是否存在合法方案
发现我们只需要对每个\(a\)的\(dp[u][a][b]\)记录最小的合法的\(b\)即可,再进一步的,如果\(a_1<a_2\),且\(b_1\leq b_2\),那么显然\(dp[u][a_2][b_2]\)就没有存在的必要了
这样,总的状态就是\(O(N\log N)\)的,转移是简单的,直接枚举左右儿子的\(dp\)即可,双指针优化一下就行,转移总复杂度依旧是\(O(N\log N)\)的
总复杂度就是\(O(N\log N\log V)\)的
P10880 [JRKSJ R9] 莫队的 1.5 近似构造
首先,因为要求的是乘积最大,所以问题转换为划分值域区间,使得每个区间的价值的乘积最大
进一步的,设当前区间的答案是\(v\),对半拆成\(\lceil\frac v2\rceil\times\lfloor\frac v2\rfloor\),发现当\(v\geq4\)的时候,这样一定是不劣的,也就是说,我们划分出的区间的值只可能为\(1/2/3\)
那么考虑对每个点\(i\),求出\(pos[k][i]\)表示以\(i\)为右端点的区间的价值为\(k\)时,最大的左区间,显然如果求出这个,就能\(O(N)\)的\(dp\)了
考虑怎么求出这个东西,考虑从题目给定的区间入手,那么即是将当前区间中的所有数排序后就能知道,对于当前区间,区间中每个数的\(pos[k][i]\),要得到真正的\(pos[k][i]\)即是将所有\(pos[k][i]\)取\(max\)即可,显然被另一个区间包含的区间是无用的,那么现在就是一些相交但不包含的区间了,即左右端点都单调递增,那么\(set\)维护一下即可,具体的就是在插入的时候更新插入的这个点的\(pos[k][i]\)和这个点后面最多\(2\)种的\(pos[k][i]\)
总复杂度\(O(N\log N+N)\)
P10882 [JRKSJ R9] ZYPRESSEN ✬✩
学会了,支配点!以前没听到过这个说法?感觉还挺有趣的,打算找几道题做
首先对值域进行分块,分成\([2^i,2^{i+1})\),那么可以发现,对于当前询问区间,找到第一个块内数量\(\geq3\)的块\(t\),那么显然块\(t\)中的前三个能直接构成一组三元组,那么如果要使得剩下的三元组比这个更优,那么一定会至少包含\(t\)之前的块中的某一个数
现在来考虑一个性质,加入我们已经确定了三元组的\(a\),那么只需要满足\(a\leq b\leq c\)且\(a+b>c\)即可,后面这个变为\(a>c-b\),又因为题目要求了\(a+b+c\)最小,所以一定有\(b\)和\(c\)是相邻的
现在我们可以知道,这个\(a\)一定是被包含在\(t\)之前的块中的,那么所有的\(a\)的数量就是\(O(\log V)\)的,考虑\(b\)和\(c\)的包含情况
- 如果\(b\)也被包含在\(t\)之前的块中
这样的\(b\)的数量是\(O(\log V)\)的,这里相当于直接遍历出所有被包含在\(t\)之前的块中的数,然后双指针一下,一个枚举\(b\),另一个从末尾往前维护最小的满足条件的\(a\)即可
- 如果\(b\)不被包含在\(t\)之前的块中
此时\(b\)的数量就不是\(O(\log V)\)的,来考虑预处理
注意到,一个数能被选做\(a\),设其所属块\(A\),一定有当前询问区间包含的数中,属于块\(A\)的不超过\(2\)个,找到这个数左边第二个属于\(A\)的数\(L\),右边第二个属于\(A\)的数\(R\),那么一个询问区间\([l,r]\)只有满足\([l,r]\in(L,R)\)才有可能会使得这个数成为\(A\)
那么显然,这样的所有\((L,R)\)的长度之和是\(O(N\log V)\)的,那么就可以对于每个数,去预处理它的\((L,R)\)区间内的可能会变成答案的三元组了,这个其实就是找支配点
再来考虑限制\(a>c-b\),把数\(x\)变成\(\lfloor\frac xa\rfloor\),那么肯定只有当\(\lfloor\frac ca\rfloor-\lfloor\frac ba\rfloor\leq 1\)才有可能满足\(a>c-b\)
当\(\lfloor\frac ca\rfloor=\lfloor\frac ba\rfloor\)时,是一定满足的,考虑求出这个情况的支配点,似乎是支配点的经典做法?
此时维护前/后缀的最小值序列,这里维护后缀的,那么就是从\(L+1\)到\(R-1\)枚举同一种向下取整值的\(i\),考虑当前加入的数\(a_i\),首先有这样一个性质,对于\(j_1<j_2\),两者都是目前序列中数,且它们是相邻的,显然点对\(k\in(j_1,j_2)\),\((k,i)\)没有\((j_2,i)\)优,也就是说,显然只有\(i\)和在序列中的点\(j\)才有可能构成支配点,已经被弹出不在序列中的就不用管了
那么当把\(a_i\)加入队列中时,它会删去末尾\(\geq a_i\)的那些\(a_j\),此时把这些弹出的\(j\)和当前\(i\)组成的点对\((i,j)\)加入支配点
,这部分的支配点数量显然是线性的,再来考虑那么不会被弹出的\(j\),对于不会被弹出的\(j_1<j_2\),这里\(j_1\)和\(j_2\)相邻,显然点对\((j_1,i)\)没有点对\((j_1,j_2)\)优,也就是说,这部分只用加入一个点对\((j',i)\)即可,这里的\(j'\)是弹出后序列中当前的最后一个\(j\),这个数量显然也是线性的
再来考虑\(\lfloor\frac ca\rfloor=\lfloor\frac ba\rfloor+1\),对于等于\(\lfloor\frac ca\rfloor\)的\(a_i\),以及等于\(\lfloor\frac ba\rfloor\)的\(a_{j_1}\),\(a_{j_2}\),有\(j_1<j_2\),考虑以下几种情况:
\(j_1<j_2<i\),此时显然\((j_1,j_2)\)优于\((j_1,i)\),那么此时只会加入\((j_2,i)\)
\(i<j_1<j_2\)同理只会加入\((i,j_1)\)
也就是说,对于\(i\),只会加入其左边第一个和右边第一个\(\lfloor\frac ca\rfloor-1\)的值作为支配点,那么这部分总的点数就是\(O(N\log V)\)的
总复杂度\(O(N\log V\log N+q\log V)\)
CF2019C Cards Partition
设\(sum\)表示牌的总数,那么有\(sum=sz\times len\),其中\(sz\)是牌组的数量,\(len\)的每个牌组的大小,显然有\(len\leq n\)
根据鸽巢原理,可知道只要\(sz\geq\max{c_i}\),就能使得每个牌组中没有相同的牌了,其中\(c_i\)表示当前第\(i\)种牌的数量
显然最优情况下有:\(\max{c_i}=\max(\max{a_i},\lceil\frac{sum}n\rceil)\),把\(sum\)拆开可以得到\(sz\geq\max(\max{a_i},\lceil\frac{sz\times len}n\rceil)\),而又因为\(len\leq n\),所以一定有\(sz\geq\lceil\frac{sz\times len}n\rceil\),那么就只需要\(sz\geq\max{a_i}\)即可
那么问题就变成找到最大的\(len\),使得存在\(sz\)(\(sz\geq\max{a_i}\))满足\(len\times sz\in[sum_0,sum_0+k]\),这里的\(sum_0=\sum a_i\),即\(sz\in[\lceil\frac{sum_0}{len}\rceil,\lfloor\frac{sum_0+k}{len}\rfloor]\),所以只需要满足\(\lceil\frac{sum_0}{len}\rceil\geq\lfloor\frac{sum_0+k}{len}\rfloor\)且\(\max{a_i}\leq\lfloor\frac{sum_0+k}{len}\rfloor\)即可
先只考虑后面这个限制,此时可二分或直接算出满足条件的最大的\(len'\),显然有可能不满足前面那个条件,注意到\(1\sim len'\)都是满足后面那个条件的,且\(1\)一定会满足第一个条件,又因为\(len'\leq n\),所以直接判当前\(len'\)是否满足第一个条件,不满足就\(--\)
复杂度\(O(N)\)或\(O(N+\log V)\)
CF2019D Speedbreaker
若已确定从城市\(t\)开始,那么显然先找到\(a_i\)最小的那么\(i\),设它们中最小的为\(l\),最大的为\(r\),那么显然当前合法的充要条件是\(\max(r,t)-\min(l,t)+1\leq a_i\)
再找到第二小的,\(a_j\),设为\(a_j\)的点对应的区间为\([a,b]\),那么现在总的会覆盖到的就是\([\min(l,a,t),\max(r,b,t)]\),只需要这个区间的长度\(\geq a_j\)即可
然后就这样一直判下去
发现只要当前总区间(即\([\min(l_1,l_2,...,l_k),\max(r_1,r_2,...,r_k)]\))包含了\(t\),那么之后的就没区别了
考虑先找出每个前缀的总区间,枚举当前城市\(t\),二分到第一次区间包含\(t\)的位置\(k\),则首先\(k\)及之后的只需要满足前缀的总区间长度\(\leq\)当前的\(a\)的大小即可,对于之前的,显然要么全都在\(t\)的左边,要么全都在右边,此时它们对应的真正的区间会增加一部分,以全部在左边为例,假设当前区间为\([l,r]\),那么实际应该是\([l,t]\),也就是说,长度从\(r-l+1\)变成了\(t-l+1\),那么变成满足\(a_i\geq t-l+1\),只需要求出最小的\(a_i+l-1\),判断是否\(\geq t\)即可
复杂度\(O(N\log N)\)
CF2019E Tree Pruning
枚举最终叶子到根的距离\(len\),那么显然只有位于一个深度为\(len\)的点\(x\)到根的路径上的点才能保留下来,那么虚树即可
复杂度\(O(N\log N)\)
CF2018D/CF2019F Max Plus Min Plus Size ✯
唐了/ll
首先能知道必选最大值,证明考虑设最大值为\(mx\),当前最大值为\(x\),那么如果\(mx\)可以直接选进当前序列中,那就选,显然此时最大值为\(mx\),如果不能选,最劣的情况就是和\(mx\)相邻的两个数都被选了且都不是最小值,发现此时答案的增量为\(-1+mx-x\),显然啊\(mx-x\geq 1\),那么就一定不劣
现在考虑来维护最小值\(mn\),从大到小枚举\(mn\),每次相当于插入了一些数,发现此时会有一些块,且块与块之前显然互不干涉,如果块长度为\(len\),那么显然最多能选\(\lceil\frac{len}2\rceil\),所以此时答案大概是\(\sum_i\lceil\frac{len_i}2\rceil\)的样子,但是注意到我们必须要选到最大值,所以对每个块\(i\),考虑怎么算\(f_0(i)\)和\(f_1(i)\)分别表示当前块不保证选到最大值的最大数量和保证选到最大值的最大数量
显然\(f_0(i)=\lceil\frac{len_i}2\rceil\),如果块\(i\)中不存在最大值,那么\(f_1(i)=0\),否则分类一下,发现当\(len_i\)为偶数时,一定能选到\(\lceil\frac{len_i}2\rceil\)个,而\(len_i\)是奇数时,如果奇数位上存在最大值,那么就是\(\lceil\frac{len_i}2\rceil\),否则就是\(\lfloor\frac{len_i}2\rfloor\)
并查集乱搞就行,复杂度是\(O(N\log N)\)的
CF2018E1/E2 Complex Segments ✯✩
好牛啊
先简化一下题意,就是要求每个子集都是一个团,且团与团之间没有边,且显然一个团中必存在一个点,使得所有边都包含了它,那么其实就相当于把序列划分成了很多段,然后每个团的边在被完全包含与当前段中的边中选
首先看到\(E1\)的数据范围,\(2e4\),很根号,考虑根号分治
因为题目要求\(sz\times len\),其中\(sz\)是每个子集的大小,\(len\)为数量,且我们知道,\(sz\times len\geq n\),也就是说,有:
- \(sz\leq B\),\(len\geq\frac nB\)
- \(sz>B\),\(len<\frac nB\)
那么上面那种情况取\(sz\)来算,下面取\(len\)来算
考虑已知\(sz\),求最大的\(len\),考虑\(dp\),记\(dp[i]\)为只考虑前\(i\),最大的\(len\),注意到,若当前段的右端点为\(i\),满足区间\([l,r]\)中团的大小\(\geq sz\)的\(l\)是一段前缀,那么显然找到最大的那个\(l'\),转移就有\(dp[i]=\max(dp[i-1],dp[l'-1]+1)\)
然后又可以发现,当\(i+1\)时,\(l'\)也是递增的,而根据团必有一个所有边都经过的点,只需要用线段树维护一下当前区间内的点被区间内的边覆盖的次数即可
那么可以\(O(N\log N)\)完成一次找\(len\)
若固定\(len\),因为显然有\(sz\)越大,找到的\(len\)越小,所以二分到对应\(len\)大于等于当前\(len\)的最大的\(sz\)即可
那么这部分复杂度是\(O(BN\log N+\frac NB\log^2N)\)的,取\(B=\sqrt(N\log N)\)即可取得最优复杂度\(O((N\log N)^{\frac 32})\),可以过掉\(easy\ version\)
考虑优化,这里把查找\(len\)的复杂度优化到\(O(N\alpha(N))\)
突然想起我之前算复杂度都把\(\alpha(N)\)当\(\log N\)算,蚌埠住了
首先把区间变成不交的,显然可以有在新的区间有交当且仅当在原先的区间有交
将原本维护的覆盖次数序列\(c_i\)替换成\(d_i\),满足\(d_i=\max_{j\geq i}c_j\),即后缀最大值序列,又因为现在的区间是不交的了,所以显然可以发现,\(d_i-d_{i-1}\leq 1\),所以现在又改为维护\(d_i\)的差分序列\(c_i\)
考虑变化,对于当前维护的区间\([l,r]\),现在让\(r+1\),如果以\(r+1\)为右端点的区间\([a,r+1]\)是属于\([l,r]\)的,那么\(c_{r+1}=1\),\([1,a-1]\)中最后一个\(c_k=1\)的\(c_k\)变成\(0\),没有就不变;从\(l\)变成\(l+1\)时,如果以\(l\)为左端点的区间\([l,b]\)属于区间\([l,r]\),那么会有\([l,b]\)中最后一个\(c_k=1\)的\(c_k\)变成\(0\)
这样复杂度就是\(O(N\alpha(N))\)的了
总复杂度变成\(O(BN\alpha(N)+\frac NB\log N\alpha(N))\),总复杂度\(O(N\sqrt N\alpha(N)\sqrt{\log N})\),题解说的是\((N\sqrt N\alpha(N))\)啊,不知道是直接剩了后面那个\(\sqrt{\log N}\)还是我唐了其实没有这个
感觉很卡常,卡了几下还没卡过去,摆烂了喵
有\(O(N\sqrt N)\)的做法,https://codeforces.com/blog/entry/134445,但是没太懂,脑子想不动了,等以后想看了再回来看(