第一步,观察都所有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; } } }