1. 程式人生 > 實用技巧 >CF837G Functions On The Segments

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