线段树合并炸了,#2开始就过不掉了,求助好心人!
变量同题意,n,m反过来了,rt存的是根节点编号,merge是合并操作,update是单点修改,query求的是前k小的和,kth求的是第k小
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
void read(int &x){
int k=1;char c=getchar();x=0;
while(c>'9'||c<'0'){if(c=='-')k=-1;c=getchar();}
while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
x*=k;return;
}
const int N=400005,M=8000005;
int n,m,x,y,pre=1,s,ans,l,r,z,k,w,rt[N],lc[M],rc[M],t[M],a[N],b[N],cnt=0,tot;
int L[N],R[N],W[N],f[M];
int lsh(int x){return lower_bound(b+1,b+cnt+1,x)-b;}
int update(int rt,int l,int r,int x,int y){
if(!rt) rt=++tot;
if(l==r){t[rt]+=y;if(y>0)f[rt]++;else f[rt]--;return rt;}
int mid=l+r>>1;
if(x<=mid) lc[rt]=update(lc[rt],l,mid,x,y);
else rc[rt]=update(rc[rt],mid+1,r,x,y);
t[rt]=t[lc[rt]]+t[rc[rt]];
f[rt]=f[lc[rt]]+f[rc[rt]];
return rt;
}
int merge(int l,int r){
if(!l||!r) return l+r;
int x=++tot;t[x]=t[l]+t[r];f[x]=f[l]+f[r];
lc[x]=merge(lc[l],lc[r]);
rc[x]=merge(rc[l],rc[r]);
return x;
}
int query(int rt,int l,int r,int x){
if(l==r){
if(x>=f[rt])return t[rt];else return l*x;
}
int mid=l+r>>1;
if(x<=f[lc[rt]]) return query(lc[rt],l,mid,x);
return query(rc[rt],mid+1,r,x-f[lc[rt]])+t[lc[rt]];
}
int kth(int rt,int l,int r,int x){
if(l==r) return l;
int mid=l+r>>1;
if(x<=f[lc[rt]]) return kth(lc[rt],l,mid,x);
return kth(rc[rt],mid+1,r,x-f[lc[rt]]);
}
int main(){
read(n);read(m);
for(int i=1;i<=n;i++){
read(L[i]);read(R[i]);read(W[i]);
b[i]=W[i];
}
sort(b+1,b+n+1);cnt=unique(b+1,b+n+1)-b-1;
for(int i=1;i<=n;i++){
W[i]=lsh(W[i]);w=W[i];l=L[i];r=R[i];
rt[l]=update(rt[l],1,n,W[i],b[W[i]]);
rt[r+1]=update(rt[r+1],1,n,W[i],-b[W[i]]);
}//puts("\n");
for(int i=1;i<=m;i++){
rt[i]=merge(rt[i-1],rt[i]);
}
for(int i=1;i<=m;i++){
read(w);read(x);read(y);read(z);
k=1+(x*pre+y)%z;
// printf("K=%d\n",k);
if(k>=f[rt[w]]) ans=t[rt[w]];
else ans=query(rt[w],1,n,k);
printf("%d\n",ans);
pre=ans;
}
return 0;
}