强制在线,那就看看能不能套一些数据结构上去,发现这是个分段函数
我们要求的又是一段区间内的值,因此分两点考虑
区间值是否可以通过前缀和查询,在这个基础上,如何维护前缀和信息。
考虑使用主席树来维护区间,那么在做每个点的时候,我们发现这是一段分段函数,也就是对于值域来说,可以差分的维护信息,这样只要求1-x的信息,就知道了x在这个点的真实前缀和答案
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,int> plll; const int N=2e5+10; const int inf=0x3f3f3f3f; const int mod=1e9; int a[N],b[N],x1[N],x2[N],y1[N],y2[N]; struct node{ int l,r; ll a,b,y1,y2; }tr[N*30]; int rt[N]; int idx; int tmp1,tmp2,tmp3,tmp4; void modify(int &p,int q,int l,int r,int pos){ p=++idx; tr[p]=tr[q]; tr[p].a+=tmp1,tr[p].b+=tmp2,tr[p].y1+=tmp3,tr[p].y2+=tmp4; if(l==r){ return ; } int mid=l+r>>1; if(pos<=mid) modify(tr[p].l,tr[q].l,l,mid,pos); else modify(tr[p].r,tr[q].r,mid+1,r,pos); } ll query(int p,int l,int r,int L,int R,ll x){ if(L<=l&&R>=r){ return tr[p].a*x+tr[p].b+tr[p].y1+tr[p].y2; } int mid=l+r>>1; ll ans=0; if(L<=mid) ans+=query(tr[p].l,l,mid,L,R,x); if(R>mid) ans+=query(tr[p].r,mid+1,r,L,R,x); return ans; } int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i; for(i=1;i<=n;i++){ //差分维护 cin>>x1[i]>>x2[i]>>y1[i]>>a[i]>>b[i]>>y2[i]; tmp1=0,tmp2=0,tmp3=y1[i],tmp4=0; modify(rt[i],rt[i-1],1,N,1); tmp1=a[i],tmp2=b[i],tmp3=-y1[i],tmp4=0; modify(rt[i],rt[i],1,N,x1[i]+1); tmp1=-a[i],tmp2=-b[i],tmp3=0,tmp4=y2[i]; modify(rt[i],rt[i],1,N,x2[i]+1); } int m; cin>>m; ll last=0; while(m--){ ll l,r,x; cin>>l>>r>>x; x=(x+last)%mod; ll t=query(rt[r],1,N,1,x,x)-query(rt[l-1],1,N,1,x,x); last=t; cout<<last<<endl; } }
CF837G Functions On The Segments
原文:https://www.cnblogs.com/ctyakwf/p/14057707.html