线段树合并60分求助,点点有惊喜
查看原帖
线段树合并60分求助,点点有惊喜
226523
RAYMOND_7楼主2021/1/27 21:26

线段树合并炸了,#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;
}
2021/1/27 21:26
加载中...