2021.08.18-2021.09.03
【CF#741 Div.2】
https://codeforces.com/contest/1562/problem/A, (这A题好难)给你(l,r),问最大可能的(amod b)((l leq bleq aleq r))。
先是想要让(a=b-1),但(ageq b),然后就想着取(lleq bleq a=2b-1leq r),右边得到(bleq lfloorfrac{r+1}{2} floor),左边就是条件(lleqlfloor frac{r+1}{2} floor),而仔细想想,对于(lgeq lfloor frac{r+1}{2} floor)的情况,直接取(b=l,a=r)就行。
第一题好难。
https://codeforces.com/contest/1562/problem/B, 给你一个数位可以很长的数(且不包括数位0),删掉尽可能多的数位,使得剩下的数字not prime,输出剩下的数(保证存在答案)。
这题限制挺宽的,最好的情况就是剩一个1,4,6,8,9,所以如果有就直接输出,不然的话如果有2个({2,3,5,7})也很好,再不然说明(2,3,5,7)都最多只有一个,暴力搜一下。
https://codeforces.com/contest/1562/problem/C, 给一个二进制串,要你找((l_1,r_1),(l_2,r_2)):
- 区间长度超过(n/2)
- 两个区间不完全相同
- 存在一个((l_1,r_1))的子串(s)和((l_2,r_2))的子串(t),使得(s)的十进制数是(t)的倍数。
有点像脑筋急转弯,首先是“xxxxx0”可以写成"xxxxx"的两倍,以及"0xxx"和"0xxx"是一样的,所以有0就直接找,否则就是全都是1的情况,注意((2^k-1)|(2^{km}-1))的,靠着这个性质,全1的情况取(len=n/2),区间取([1,len],[1,2len])即可(看了下题解我还想多了,直接用([1,n-1],[2,n])就行了吼)。
https://codeforces.com/contest/1562/problem/D2, 题意懒得翻了。
首先我是先想([1,n])的询问怎么做,记(s(l,r))是((l,r))的sign-variable sum,那删掉(x)就会导致(S=s(1,n))变成(s(1,n)pm a_x -2s(x+1,n)),奇偶性改变!进一步推出删2个奇偶性不变,以及删2个的情况可以通过删第一个转变成奇数的情况,所以我们就只考虑奇数的情况:
(n)是奇数则(S)也是奇数,如果删掉第一个元素,就变成是(Spm 1),如果删掉最后一个就变成(-Spm 1),这两个东西要么有一个是0(此时(|S|=1)),否则(|S|>1),两个一定异号,而如果删(x)的sum变成删(x+1)的sum,这里sum的变化是(pm(a_x+a_{x+1})in{0,-2,2}),类似介值定理的东西告诉我们这里一定有零点。
上面这个思路就能比较简单地解决第一问D1:如果区间和是0就直接0,否则奇数1偶数2。
而对于第二问偶数2的情况,也可以通过删一个(l)来变成奇数的情况(因为上面的分析,一定是有解的)。具体找位置就用二分:虽然不单调,但找零点还是可以的。QAQ记得特判一下(l=r)的情况。
【CF#736 Div.2&CF#736 Div.1】
https://codeforces.com/contest/1549/problem/A, 给一个素数(pgeq 5),找到任意一组(a,b:pmod a=pmod b,(a<bleq p))。
注意(pgeq 5),直接取(a=2,b=p-1)即可。(翻了翻我当时的代码,当时没看到题目说素数,多一个偶数的情况就是取(a=2,b=p))。
https://codeforces.com/contest/1549/problem/B, 一个象棋棋盘,两行,第一行给出地方pawn的位置,第二行是你的pawn的位置,假设你的兵在((i,j)),它可以跳到((i-1,j-1))或者((i-1,j+1))(如果目标位置有敌兵),或者如果((i-1,j))是空的,可以直接走到((i-1,j)),问有多少个pawn能走到第一行。
一个小贪心,从左往右扫一遍,按照左中右的顺序跳。
https://codeforces.com/problemset/problem/1548/A, 第(i)个人的power是(i),三种操作,(u,v)连一条边,删去(u,v)的边,以及询问:对于每个人(x),所有和他连边的,如果有比他大的,就淘汰掉(x),一直操作直到没有人被淘汰。
容易猜到一个性质:一个人能活下来当且仅当,(x)比所有和他连边的人都要大,否则一定是一连串地删人。然后这题因为保证没有重边,就可以维护每个结点的度数,以及有关系的、比他小的结点的个数,就可以线性地实现这个。
https://codeforces.com/problemset/problem/1548/B, 给一个序列,问最长能找多长的一个子段([l,r]:exist m>1:a_lmod m=a_{l+1}mod m=dots=a_rmod m)。
一开始卡在第一步惹,其实就是如果真的去考虑模数好像没法考虑,复杂度降不下来,稍微转个弯去想差分,约束就可以等价成(a_{l+1}-a_{r}equiv a_{l+2}-a_{l+1}dots(mod m)),也就是(gcd(a_{l+1}-a_l,dots,a_{r}-a_{r-1})>1),(gcd)有单调性,静态区间GCD本质就是个区间min,可以用ST表维护,枚举左端点二分右端点就行。
这题的复杂度很有意思,看起来是(O(nlog n log M))((M)是值域),因为我们之前说求(gcd(a,b))的复杂度是(O(log(min(a,b))))的,但其实有更紧的界(O(log (min(a,b)/gcd(a,b))))——因为求((a,b))和求((a/(a,b),b/(a,b)))的操作次数其实是一样的。
对数里的除法变成减法,这个性质就会导致你在求一段东西的gcd的时候,(O(nlog M))这个东西会变成(O(n)),直观感觉就是gcd是越求越小的,代价也是越来越低。
https://codeforces.com/problemset/problem/1548/C, 抛开描述题面,其实对每个(x),求(C_3^x+C_6^x+dots C_{3k}^x),(nleq 10^6)。
首先是一个性质,(sum_{k=0}^ninom{k}{x}=inom{n+1}{x+1}):右边是从(n+1)个物品选出(x+1)个物品的方案数,左边看成是在枚举选出物品标号的最大值是(k+1)(从1开始),再从剩下(k)个物品选(x)个的方案数。
然后就可以dp:记(dp[x][j])表示(sum_{k=0}^{n}inom{3k+j}{x},(j=0,1,2))。那么(dp[x][0]+dp[x][1]+dp[x][2]=sum_{k=0}^{3n+2}inom{k}{x}=inom{3n+3}{x+1}),以及由(inom{n}{m}=inom{n-1}{m-1}+inom{n-1}{m})就有(dp[x][1]=dp[x-1][1]+dp[x][0])和(dp[x][2]=dp[x-1][2]+dp[x][1]),就可以递推出所有的(dp[][])了。
【CF Global Round15】
https://codeforces.com/problemset/problem/1552/A, 把字符串排序好得到(t[1,dots,n]),把(str[i] eq t[i])的抽出来就行。
https://codeforces.com/problemset/problem/1552/B, 虽然在这里可能会存在(a<b,b<c)但是(a>c)的情况,但我们依然可以重载小于号,从左到右取max,如果(x)符合答案的条件,一定会被取到,同时再check一边是否比别的都要大就行。
https://codeforces.com/problemset/problem/1552/C, 卡了许久,题目有一句话很关键:o point strictly inside the circle belongs to all 3 chords.也就是只要有交叉就会多一个交点,不用管三线共点的情况。于是可以证明,最优的染色方法是把剩下的(2(n-k))个点拎出来重新标号,然后按照第(i)个点连接(i+(n-k))来连线(假设原本是(a-b,c-d)这样没有交叉的连接,如果换成(a-c,b-d)这样有交叉的连法,交点至少不会变少)。
https://codeforces.com/contest/1552/problem/D, 给一个(a[1,dots,n]),问是否存在(b[1,dots,n]:)对所有(a_i)存在(1leq j,kleq n:a_i=b_j-b_k),这题(nleq 10)。
(n)只有10看着就很乱搞…首先(b)的一个差分一定能搞定一个(a_i),所以(n)个位置至少能解决(n-1)个(a_i),问题就是剩下一个怎么搞定。
如果(a_i=0)或者(a_i=a_j),就可以少用一个(b)的代价,这时候一定是YES,进一步,只要能找到(a[1,dots,n])的一个子序列(pm a_{p_1}pm a_{p_2}dotspm a_{p_k}=0)就行,当然这只是充分条件,但我们猜他必要,于是(O(n3^n))暴力枚举试着交一发,过了,好那他就是必要条件了(bushi)。
[必要性]假设存在符合条件的(b)数组,考虑张(n)个点的图,每个点的点权是(b_i),接着因为每个(a_i)都能写成(b_{j_i}-b_{k_i})的形式,我们连一条((j_i,k_i))的边权为(a_i)的边,这样就构成了一个(n)个顶点(n)条边的图,(|V|=|E|=n,|V|+|F|-|E|=2),此时一定有环(此时先不考虑方向),而这个环上:
(egin{aligned}(b_{v1}-b_{v2})+(b_{v2}-b_{v3})+dots+(b_{v_{k-1}}-b_{vk})+(b_{vk}-b_{v1})=0end{aligned})
我们说每条边对应一个(a_i),那这个式子就意味着(a[1,dots,n])的一个子序列(pm a_{p1}pmdotspm a_{pk}=0),也就是我们前面的充分条件。
【CF#739 Div3】
https://codeforces.com/problemset/problem/1560/A, 暴力
https://codeforces.com/problemset/problem/1560/B, 因为是一个圈,一定有(a+n/2=b)或(b+n/2=a)之一。
https://codeforces.com/problemset/problem/1560/C, (O(sqrt k))地求出在哪一层。
https://codeforces.com/problemset/problem/1560/D, 假设当前的串是(s),要变换成目标串(t),因为只能在(s)的后面加东西,所以我们就找一个尽可能长的(s)的前缀(pre),使得它和(t)的一个子序列一样,这样就得到最小操作次数(|s|+|t|-2|pre|),再枚举答案是2的多少次幂即可。
https://codeforces.com/problemset/problem/1560/E, (这题感觉有点小码),思路很简单,先倒着从(t)里找还没出现过的字符,加到order
里,最后order
翻过来就得到删除的顺序,然后再用每个字符的出现次数算(s)的长度,从(|t|)里截取前(|s|)个字符就是(|s|),但这还不够,再把(s)和order
代回去验证一下会不会得到(t)…。
https://codeforces.com/problemset/problem/1560/F2, dfs/数位dp?