鉴于Codeforces和atcoder上有很多神题,即使发呆了一整节数学课也是肝不出来,所以就记录一下。
只要横坐标或者纵坐标超出范围就可以,所以我们只用看其中一维就可以了。
我们又知道,如果先手想要让它从左边出去,那么先手就会一直Left,后手就会一直Right。
所以枚举四种情况(L,R,U,D)就可以了。
AGC033C Removing Coins
首先我们考虑链的情况,如果选的是端点,那么有一个点没有硬币,如果选的不是端点,那么有两个点没有硬币。所以就是一个取石子问题了。两个点的情况要特殊考虑。
但是树的情况过于复杂,所以我们要选一条链来代替这整棵树,使得这条链被删完当且仅当整棵树被删完。
这条链就是这棵树的直径。
ABC126F XOR Matching
被ABC狠狠地虐了一发 。。。
设$a \oplus b=k$且$a,b,k$互不相同,则构造$a,k,a,b,\ldots,k,\ldots,b$,其中$\ldots$为除了$a,b,k$之外的所有数。
ARC080F Prime Flip
首先看到翻转一段的肯定要差分,变成了对$x_i$和$x_{i+p}$都异或1,其中$p$为3以上的质数。于是不知道为什么就想到了先配对然后每次去掉两个点。现在我们要把$x_u$和$x_v$都异或上1,肯定就是通过“一条链”从$u$到$v$。打打表就会发现:
- 若$|u-v|$为奇质数时,需要1步
- 若$|u-v|$为偶数时,需要2步(哥德巴赫猜想)
- 否则需要3步
那么就是进行配对,使得1最多,在1最多的情况下2最多。
1最多就是把奇数和偶数放在两边,差为质数的连一条边然后跑二分图。
2最多就是跑完之后把未配对的分别在一组内配对。配对完或者是剩下两个差不为奇质数的数,凑一个3.
ARC082E Convex Score
前方浪费好题现场。
注意到$2^{内部点个数}$是子集个数,所以我们对$(S,T)$计算贡献,其中$T$是$S$凸包的内部点的子集,所以$S\cup T$的凸包是$S$。所以它的贡献为$S\cup T$有凸包。
所以答案就是有凸包的子集个数。转换成没有凸包的子集个数就可以做了,时间复杂度$O(n^2\log n)$
记$B[l,r]$表示$A$翻转$[l,r]$后的字符串。
我们知道,如果$s[l]=s[r]$,那么翻转$[l,r]$和$[l+1,r-1]$是一样的,无贡献。如果$s[l]\neq s[r]$,且$B[l,r]= B[x,y]$,那么$B[l,r]$与$A$不相同的第一个位置就是$l$,最后一个不同的位置就是$r$,$B[x,y]$同理,所以$l=x,r=y$。
综上,答案为$1+s[x]\neq s[y]$的点对个数,反面考虑就可以直接$O(n)$计算了。
CF623B
发现只要确定gcd是多少就可以简单计算了。
发现第一个数和第$n$个数至少有一个会留下来,枚举是$+1,-1$还是不变。那么gcd肯定是这些的质因子。
CF901B
自闭了。。。
根据整数的欧几里得算法,取Fibonacci数列里面的数能到达复杂度上界。
那对于多项式,$p_0=1,p_1=x,p_n=xp_{n-1}\pm p_{n-2}$,那么$(p_n,p_{n-1})$就是答案。
那如何要求$p_n$的系数绝对值$\le 1$呢,取$p_n=xp_{n-1}+p_{n-2}(\mathrm{mod} \ 2)$.
感觉上是$\pm$之下$\mathrm{mod} \ 2$是不变的吧。。。但是不太会证。。。当时想到了但是不知道为什么是对的。。。
AGC039D
首先看一张图:
其中G为$\Delta ABC$的内心,证明:G为$\Delta DEF$的垂心。
证明:【略】(导角即可)
还有一个东西叫欧拉线,$\overrightarrow{OH}=\overrightarrow{OA}+\overrightarrow{OB}+\overrightarrow{OC}$。
枚举$D,E,F$计算贡献,由于是循环对称的,所以只用枚举$O(n^2)$个$D$。
AGC005C
虽然可能能做出来但是还是跑去看题解了。
我们知道,设$a,b$是树直径的端点,则$k=\max(a_i)$是直径长度,$\max_j(dis(i,j))=\max(dis(i,a),dis(i,b))$。
首先看直径上面的值,如果$k$为偶数,那么直径上面为$k,k-1,\ldots,k/2,k/2+1,\ldots,k$,如果$k$为奇数,则为$k,k-1,\ldots,(k+1)/2,(k+1)/2,\ldots,k-1,k$。首先把这些值
去除掉,如果不能直接输出Impossible.
然后看直径外面的,如果$k$为偶数,那么直径外面至少为$k/2+1$,如果$k$为奇数,那么直径外面至少为$(k+1)/2+1$,检查一下是不是就可以了。
AGC005D
(才发现这场的F题在n年前做掉了)
(看不懂题解,溜了)
AGC005E
首先,答案为-1当且仅当Red能够到达两个点$u$或$v$使得$(u,v)\in E_R$且$dis_B(u,v)\geq 3$。
那如何判断能否到达一个点$v$呢,就是$dis_R(X,v)<dis_B(Y,v)$。
用一个dfs和一个bfs就可以找出所有Red能到达的点,如果有上面条件的点则输出-1,否则输出$dis_B$的最大值。
AGC006D
首先二分答案,这样序列里面就只剩下$0/1$了。
打打表,发现答案就是离中心最近的相邻两个相等的数的值。
如果是0/1相间的,特判一下。
AGC006C
我们发现一次操作实际上就是$x_i=\frac{2x_{i+1}+2x_{i-1}-2x_i}{2}=x_{i+1}+x_{i-1}-x_i$。
这个式子之前见过一遍了,改为差分之后就相当于交换$i$和$i+1$。一共做$k$次就是先求出这个置换,然后求这个置换的$k$次方。置换的幂可以通过分解成环,然后在
每个环上做。
AGC006F
之前VK Cup好像lqy讲的一道题跟这个很像。
由于是$(u,v),(v,w)\rightarrow (w,u)$,所以考虑对每一个弱联通分量建一个三分图(逃),如果能建出来且三个分量中都有点,则为$cnt_0\times cnt_1+cnt_1\times cnt_2+cnt_2\times cnt_0$,如果能建出来而且只有两个分量有点,则什么都加不上去。如果不能建出来那么它就是一个完全图(包括自环)。
直接dfs就可以做。
CF1240B
发现自己想假了之后就直接停止了思考。。。
注意到离散化之后,不动的地方肯定是一个连续段而且位置单调不降。。。然后就没了。。。
CF1240D
要把自己做过的题记住。
AGC007F
超级神仙题。
我们画画图就会发现,$S$中相同连续的字符到$T$中相同连续的字符构成了一段折线。借一张图:
(我们定义拐点是折线中上面和右面和自己是同一个字符的格子)
那再看看,为何我们需要多次复制呢?是因为折线不能相交,左边的拐点会被右边的拐点压下去。从右到左考虑,如果这个折线的某个拐点的影响不消失,那么下一个折线必定有一个拐点是当前拐点向左向下一位。
那我们用队列维护当前折线的拐点,队列里面第$i+1$个元素(从队尾到对首)减去$i$是当前折线的从上往下第$i+1$个拐点的位置(☞第几个字符),那么在队尾加上一个数就是让前面的折线往前一位,并在后面加上一个。注意如果``q[front] - (rear - front) >= i``就说明这个拐点没用了(拐点不可能比它要后),那么答案就是队列长度最大值$+1$,因为满足当前点需要的复制次数(即行数)是拐点个数$+1$.
1 #include<bits/stdc++.h> 2 #define Rint register int 3 using namespace std; 4 const int N = 1000003; 5 int n, ans, q[N], front, rear; 6 char s[N], t[N]; 7 int main(){ 8 scanf("%d%s%s", &n, s + 1, t + 1); 9 if(!strcmp(s + 1, t + 1)){puts("0"); return 0;} 10 int cur = n; 11 for(Rint i = n;i;i --){ 12 if(t[i] == t[i - 1]) continue; 13 while(cur && (cur > i || s[cur] != t[i])) -- cur; 14 if(!cur){puts("-1"); return 0;} 15 while(front < rear && q[front] - (rear - front) >= i) ++ front; 16 if(cur != i) q[rear ++] = cur; 17 ans = max(ans, rear - front + 1); 18 } 19 printf("%d", ans); 20 }