持之以恒, "广积粮,缓称王", 每天进步一点点。
做了十几道构造题稍微总结一下:
1、前后缀贪心,比如说观察前后缀的sum,去看以后怎么考虑最好。Problem - 1903C - Codeforces
2、双指针贪心法,考虑两端相消或者相互作用,还有就是考虑左右边界。 Problem - 1891C - Codeforces
3、转换观察法,有些关系可以抽象成图,观察图的某些性质去总结规律。也可以抽象成一个集合,两个集合相等可以说明有解可构造。Problem - 1891C - Codeforces
4、打表找规律,一般没什么规律可循即可打表找规律,一般和数论有关的很喜欢考,acm也喜欢考,属于人类智慧题。Problem - 1916D - Codeforces
5、公式推导演算,常见的分为公式的等价变形、公式的化简(这个常考,一般需要先证明某些性质,可以直接抵消,一般如果原公式处理起来很复杂时就可以考虑)。Problem - 1889B - Codeforces
6、考虑奇偶数去简化问题或者分类问题,从其中的一些运算性质入手,因为奇数偶数的加减以及%运算(这个结论很重要)的结果的奇偶性是固定的,Problem - 1898C - Codeforces
7、根据性质构造模型,看看能不能分成几个块,几个不同的集合,再选择算法去解决。Problem - 1873G - Codeforces
8、考虑从小到大处理,或者是从大到小处理,有时候先处理小的对大的不会有影响,或者反过来,这样的处理顺序是最完美的。Problem - 1904D2 - Codeforces
9、边界贪心法,一般要在问题的最边界处考虑,有时候这样做结果是最优的,或者考虑边界上的影响,假如让影响最小,就使得影响<= 固定值 。 Problem - E - Codeforces and Problem - 1903C - Codeforces
Day5(思维 + 双指针贪心)Problem - D - Codeforces
题意: 给定n个区间,起始位置在0,区间的li<=ri且li>=0,ri>=0,要求按照顺序到每个区间上去,比如从起点到1区间,再从1区间到2区间...一直到n区间,一次可以跨越不超过k步,求最小的k。
题解: 最小的,而且很容易能观察出来,ans右边包括ans都是能符合条件的,ans左边都无法满足条件,具有二分的性质,然后每次到达的地方和目标区间取交集(此时维护的是一个区间,这样能覆盖所有能到达的地方,属于双指针贪心),然后往后扩展,如果是空集check失败。
代码:二分 + 双指针贪心。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int n, m;
int L[N], R[N];
bool check(int mid) {
int l = 0, r = 0;
for(int i = 1; i <= n; i ++ ) {
int can_go_l = l - mid, can_go_r = r + mid;
int use_l = max(can_go_l, L[i]), use_r = min(can_go_r, R[i]);
if(use_l > use_r) return 0;
l = use_l, r = use_r;
}
return 1;
}
void solve() {
cin >> n;
for(int i = 1; i <= n; i ++ ) cin >> L[i] >> R[i];
int l = 0, r = 1e9 + 2;
while(l < r) {
int mid = l + r >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << l << endl;
}
signed main() {
int ts;
cin >> ts;
while(ts--) solve();
return 0;
}