最近总算是开学了,然后总结一下最近的学习。
首先就是刷题方面:
补题:Codeforces Round #818 (Div. 2)
那个D题实在是想不出来他怎么变成了C(n,i)值了,有点奇怪,没有补出来,后面再想想,缓一缓。
补题:COMPFEST 14 - Preliminary Online Mirror (Unrated, ICPC Rules, Teams Preferred)
然后就是CF1800的题目训练:
这个题目感觉还可以:
写法就是预处理ST表+二分可以过
然后ST表好久没有用去复习了一下。
主要就维护一段区间的gcd,满足a%m == b%m那么只要m是a,b的公约数即可。
其中a = a2-a1, b = a3 - a2(举例)。
同理a%m == b%m == c%m即:m是a,b,c的公约数即可。所以题目就是维护区间公约数,这里方便区间合并维护所以使用最大公约数,方便扩展。然后就是求最长区间即可。
初始化ST
然后就是二分即可:
AC代码:
#include <bits/stdc++.h>
#define OST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define endl "\n"
#define ll long long
using namespace std;
const int N = 2e5 + 10;
ll Log[N], a[N];
ll f[N][21];
int n;
void init() {
for (int i = 2; i < N; i ++) {
Log[i] = Log[i >> 1] + 1;
}
}
void st() {
for (int i = 1; i < n; i ++) {
f[i][0] = abs(a[i + 1] - a[i]);
}
for (int i = 1; i <= 20; i ++) {
for (int j = 1; j + (1 << i) <= n; j ++) {
f[j][i] = __gcd(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]);
}
}
}
ll ask(int l, int r) {
int k = Log[r - l + 1];
return __gcd(f[l][k], f[r - (1 << k) + 1][k]);
}
bool check(int mid) {
for (int i = mid; i < n; i ++) {
if (ask(i - mid + 1, i) > 1) return 1;
}
return 0;
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
if (n == 2) {
if (abs(a[2] - a[1]) == 1) {
cout << 1 << endl;
} else {
cout << 2 << endl;
}
return;
}
st();
int l = 1, r = n - 1;
while (l < r) {
int mid = (l + r + 1) / 2;
if (check(mid)) {
l = mid;
} else {
r = mid - 1;
}
}
cout << l + 1 << endl;
}
signed main() {
OST;
int T = 1;
cin >> T;
init();
while (T--) { solve(); }
return 0;
}
然后就是复习了一下图论,还有部分计算几何的知识,掌握的还不是很牢靠,感觉过两天没有用的话又会忘记,所以还是整理一下模板,然后算法原理就好,毕竟感觉这些方面平时遇到的题目有点少。但是比赛又会有,没有办法。