题目链接:
solution:
主席树难题.区间修改单点查询,这本是普通线段树可以做到的.但本题思维难度较大,要求我们求区间前$k$小,为了空间防爆,故将代价离散,然后以时间排序,主席树维护前缀和即可.
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #define R register 9 #define next awawn 10 #define debug puts("mlg") 11 #define maxn 200010 12 using namespace std; 13 typedef long long ll; 14 typedef long double ld; 15 typedef unsigned long long ull; 16 inline ll read(); 17 inline void write(ll x); 18 inline void writesp(ll x); 19 inline void writeln(ll x); 20 ll m,n; 21 struct node{ 22 ll x,z; 23 bool operator < (const node &X)const{return x<X.x;} 24 }a[maxn<<1]; 25 struct Node{ 26 ll ls,rs,cnt,sum; 27 }t[maxn<<5]; 28 ll tot,q,K,b[maxn]; 29 ll rt[maxn<<5],Cnt; 30 ll p,pre=1; 31 32 inline void build(ll &Rt,ll l,ll r){ 33 Rt=++Cnt; 34 if(l==r) return; 35 ll mid=l+r>>1; 36 build(t[Rt].ls,l,mid);build(t[Rt].rs,mid+1,r); 37 } 38 39 inline ll update(ll fa,ll l,ll r,ll k){ 40 ll Rt=++Cnt; 41 t[Rt]=t[fa]; 42 if(l==r){ 43 t[Rt].cnt+=k; 44 t[Rt].sum+=k*b[p]; 45 return Rt; 46 } 47 ll mid=l+r>>1; 48 if(p<=mid) t[Rt].ls=update(t[Rt].ls,l,mid,k); 49 else t[Rt].rs=update(t[Rt].rs,mid+1,r,k); 50 t[Rt].cnt=t[t[Rt].ls].cnt+t[t[Rt].rs].cnt; 51 t[Rt].sum=t[t[Rt].ls].sum+t[t[Rt].rs].sum; 52 return Rt; 53 } 54 55 inline ll query(ll Rt,ll l,ll r,ll k){ 56 if(l==r){return t[Rt].sum/t[Rt].cnt*k;} 57 ll mid=l+r>>1; 58 if(k<=t[t[Rt].ls].cnt) return query(t[Rt].ls,l,mid,k); 59 else return t[t[Rt].ls].sum+query(t[Rt].rs,mid+1,r,k-t[t[Rt].ls].cnt); 60 } 61 62 int main(){ 63 n=read();m=read(); 64 for(R ll i=1;i<=n;i++){ 65 a[++tot].x=read();a[++tot].x=read()+1; 66 a[tot-1].z=b[i]=read();a[tot].z=-b[i]; 67 } 68 sort(a+1,a+tot+1);sort(b+1,b+n+1); 69 q=unique(b+1,b+n+1)-b-1; 70 for(R ll i=1;i<=tot;i++){ 71 while(K<a[i].x) rt[K+1]=rt[K],++K; 72 if(K==n+1) break; 73 p=lower_bound(b+1,b+q+1,abs(a[i].z))-b; 74 rt[K]=update(rt[K],1,q,a[i].z>0?1:-1); 75 } 76 for(R ll i=1,x,a,b,c;i<=m;i++){ 77 x=read();a=read();b=read();c=read(); 78 ll k=(a*pre+b)%c+1; 79 if(k>=t[rt[x]].cnt){ 80 writeln(pre=t[rt[x]].sum); 81 } 82 else{ 83 writeln(pre=query(rt[x],1,q,k)); 84 } 85 } 86 } 87 inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;} 88 inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');} 89 inline void writesp(ll x){write(x);putchar(' ');} 90 inline void writeln(ll x){write(x);putchar(' ');}