KYOCERA Programming Contest 2023(AtCoder Beginner Contest 305)
D题:二分答案:
读这个题目的时候我就意识到了二分:
学会了lower_bound和upper_bound,低级的就是多了一个相等
题意:这个题意也是非常经典的题意,这个的题意非常的简单,我刚开始还没有读懂,有些题目可能上来,说一些没有用的话,其实题意很简单
1怎样做:这里涉及到一个非常经典的问题:早饭的时候我总共是偷玩了A[time[早饭]]分钟的游戏,午饭时我总共是偷偷的玩了A[time[早饭]]分钟的游戏,现在我想知道在早饭和中午饭之间的一次上厕所的时间是time[上厕所],我想知道截至到上厕所,我一共是偷玩了多少时间A[time[上厕所]](time都是知道的):A[time[早饭]] + (time[午饭] - time[wc])* (A[午饭] - A[早饭]),因为这个东西是线性的
2为什么:二分答案的话能够用很短的时间找到位置
3下次如何想起来:二分答案的题目,往往是非常经典的题目:
4这个是累计区间问题
5注意一下这个题目的代码,A[i]往后面延迟了一位,a[i]睡眠时间对应的是A[i + 1]的睡眠时间
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
long long a[N],A[N];
int n;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n;
for(int i = 1;i <= n;i ++) cin >> a[i];
for(int i = 1;i <= n;i ++){
if(i % 2 != 0) A[i] = A[i - 1] + a[i] - a[i - 1];
else A[i] = A[i - 1];
}
int cnt;
cin >> cnt;
while(cnt --){
int l,r;
cin >> l >> r;
int i = upper_bound(a + 1,a + n,l) - a - 1;
long long L = A[i] + (l - a[i])* (A[i + 1] - A[i])/(a[i + 1] - a[i]);
int j = upper_bound(a + 1,a + n,r) - a - 1;;
long long R = A[j] + (r - a[j])* (A[j + 1] - A[j])/(a[j + 1] - a[j]);
cout << R - L << endl;
}
return 0;
}