CF862E Mahmoud and Ehab and the function(二分)

第一步,观察都所有a数组都要用到,因此先预处理a的答案

对于b数组来说,也是间隔正负,并且我们发现随着j的移动就是少了前面的多了后面的。

因此我们考虑使用前缀和来处理每一个j产生的答案。

我们发现b数组在之后是不会变化的,只有a数组会变化,因此我们只需要根据a数组找最接近他的b值即可

这就想到了二分。现在有个问题就是a数组的修改,我们发现这个修改是假的,只需要讨论l,r的奇偶性即可知道多加了x还是减少了x

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+10;
ll a[N],b[N];
ll s[N];
vector<ll> num;
int main(){
    ios::sync_with_stdio(false);
    int n,m,q;
    cin>>n>>m>>q;
    int i;
    ll sum=0;
    for(i=1;i<=n;i++){
        cin>>a[i];
        if(i%2){
            sum+=a[i];
        }
        else{
            sum-=a[i];
        }
    }
    s[0]=0;
    for(i=1;i<=m;i++){
        cin>>b[i];
        if(i%2){
            s[i]=s[i-1]+b[i];
        }
        else{
            s[i]=s[i-1]-b[i];
        }
    }
    for(i=0;i<=m-n;i++){
        ll tmp=s[i+n]-s[i];
        if(i%2){
            tmp=-tmp;
        }
        num.push_back(tmp);
    }
    sort(num.begin(),num.end());
    num.erase(unique(num.begin(),num.end()),num.end());
    int pos=lower_bound(num.begin(),num.end(),sum)-num.begin();
    if(pos>=1){
        if(pos==(int)num.size()){
            cout<<abs(sum-num[pos-1])<<endl;
        }
        else
        cout<<min(abs(sum-num[pos]),abs(sum-num[pos-1]))<<endl;
    }
    else{
        cout<<abs(sum-num[pos])<<endl;
    }
    while(q--){
        ll l,r,x;
        cin>>l>>r>>x;
        if(l%2){
            if(r%2){
                sum+=x;
            }

        }
        else{
            if(r%2==0)
                sum-=x;
        }
        int pos=lower_bound(num.begin(),num.end(),sum)-num.begin();
        if(pos>=1){
            if(pos==(int)num.size()){
                cout<<abs(sum-num[pos-1])<<endl;
            }
            else
                cout<<min(abs(sum-num[pos]),abs(sum-num[pos-1]))<<endl;
        }
        else{
            cout<<abs(sum-num[pos])<<endl;
        }
    }
}
View Code

 

posted @ 2020-09-22 19:01  朝暮不思  阅读(174)  评论(0编辑  收藏  举报