C. Present (Thinking + Dichotomy + Difference/Line Segment Tree/Tree Array)

https://codeforces.com/problemset/problem/460/C


Ideas:

Considering the maintenance of i, the one in front of i has been maintained, so add and subtract the interval after it

Since each number is not >=x, it must be added, and the interval ++ is also given to the back. In the process of difference, the simple next updated value can be maintained while scanning.

Of course, you can also maintain the interval sum and single-point query in a tree array/line segment tree

Forcibly 1e16 burst ll. Changed to 128

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL cnt[maxn],a[maxn],b[maxn];
bool check(LL x,LL n,LL m,LL w){
    for(LL i=1;i<=n;i++) cnt[i]=a[i]-a[i-1];
    __int128 sum=0;
    for(LL i=1;i<=n;i++){
       cnt[i]+=cnt[i-1];
       if(cnt[i]<x){
          __int128 k=x-cnt[i];
          sum+=k;
          cnt[i]+=k;
          if(i+w<=n) cnt[i+w]-=k;
       }
    }
    if(sum<=m) return true;
    else return false;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m,w;cin>>n>>m>>w;
  for(LL i=1;i<=n;i++){
    cin>>a[i];
    b[i]=a[i];
  }
  LL l=0;LL r=1e16;
  while(l<r){
    LL mid=(l+r+1)>>1;
    if(check(mid,n,m,w)) l=mid;
    else r=mid-1;
    for(LL i=1;i<=n;i++) a[i]=b[i];
  }
  cout<<l<<"\n";
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/114945544