题解:AT_abc395_f [ABC395F] Smooth Occlusion
Lovely_yhb · · 题解
题意
有两个长度为
- 存在
H 使所有u_i+d_i=H 。 - 序列中相邻两个数的差小于等于
x 。
思路
这道题可以二分答案去做。
只需要确定
二分答案
设
因为每次操作只能减少,所以有
对于
又因为每个数都要大于等于
对每个
第
- 自身的区间
[\max(0,H-d_i),\min(u_i,H)] 。 - 能够和前一个数的差不超过
x ,即必须落在区间[L_{i-1}-x,R_{i-1}+x] 内。
因此,对每个
如果对于某个
AC Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,x,u[N],d[N];
bool check(int H) {
int L=max(0ll,H-d[1]),R=min(u[1],H);
if(L>R) return 0;
for(int i=2;i<=n;i++){
int curL=max(0ll,H-d[i]),curR=min(u[i],H);
curL=max(curL,L-x),curR=min(curR,R+x);
if(curL>curR) return 0;
L=curL,R=curR;
}
return 1;
}
signed main() {
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>x;
int sum=0;
for(int i=1; i<=n; i++) cin>>u[i]>>d[i];
for(int i=1; i<=n; i++) sum+=u[i]+d[i];
int maxn=1145141919810ll;
for(int i=1; i<=n; i++) maxn=min(maxn,u[i]+d[i]);
int l=0,r=maxn,anss=0;
while(l<=r) {
int mid=(l+r)/2;
if(check(mid)) anss=mid,l=mid+1;
else r=mid-1;
}
cout<<sum-n*anss;
return 0;
}