CF837G Functions On The Segments

强制在线,那就看看能不能套一些数据结构上去,发现这是个分段函数

我们要求的又是一段区间内的值,因此分两点考虑

区间值是否可以通过前缀和查询,在这个基础上,如何维护前缀和信息。

考虑使用主席树来维护区间,那么在做每个点的时候,我们发现这是一段分段函数,也就是对于值域来说,可以差分的维护信息,这样只要求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;
    }
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/14057707.html