蒟蒻树套树RE求助
查看原帖
蒟蒻树套树RE求助
198716
Tom俩楼主2021/7/1 11:11

RT,蒟蒻用线段树套平衡树写,RE了好几个点,请问各位大佬为什么会RE呢?

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<vector>
#define ls (u<<1)
#define rs ((u<<1)|1)
using namespace std;
const long long inf=0x3f3f3f3f3f3f3f3f;
const int N=50005;
int cnt,size[N*100],num[N*100],rd[N*100],son[N*100][2];
long long v[N*100];
void pushup(int p) {
	size[p]=size[son[p][0]]+size[son[p][1]]+num[p];
}
void rotate(int &p,int d) {
	int k=son[p][d^1];
	son[p][d^1]=son[k][d];
	son[k][d]=p;
	pushup(p);
	pushup(k);
	p=k;
}
void ins(int &p,long long x,int c) {
	if(!p) {
		p=++cnt;
		size[p]=c;
		num[p]=c;
		v[p]=x;
		rd[p]=rand();
		return;
	}
	if(v[p]==x) {
		num[p]+=c;
		size[p]+=c;
		return;
	}
	int d=(x>v[p]);
	ins(son[p][d],x,c);
	if(rd[p]<rd[son[p][d]]) {
		rotate(p,d^1);
	}
	pushup(p);
}
long long Rank(int p,long long x) {
	if(!p)return 0;
	if(v[p]==x)return size[son[p][1]];
	if(v[p]>x)return size[son[p][1]]+num[p]+Rank(son[p][0],x);
	if(v[p]<x)return Rank(son[p][1],x);
}
int n,m,rt[N*4];
vector<long long>tag[N*4];
void pushdown(int u,int l,int r) {
	int mid=(l+r)>>1;
	for(int i=0; i<tag[u].size(); i++) {
		ins(rt[ls],tag[u][i],mid-l+1);
		tag[ls].push_back(tag[u][i]);
		ins(rt[rs],tag[u][i],r-mid);
		tag[rs].push_back(tag[u][i]);
	}
	tag[u].clear();
}
void update(int u,int l,int r,int x,int y,int v) {
	ins(rt[u],v,min(r,y)-max(l,x)+1);
	if(x<=l&&r<=y) {
		if(l!=r)tag[u].push_back(v);
		return;
	}
	int mid=(l+r)>>1;
	pushdown(u,l,r);
	if(x<=mid)update(ls,l,mid,x,y,v);
	if(y>mid)update(rs,mid+1,r,x,y,v);
}
long long queryrank(int u,int l,int r,int x,int y,long long k) {
	if(x<=l&&r<=y)return Rank(rt[u],k);
	int mid=(l+r)>>1;
	pushdown(u,l,r);
	long long res=0;
	if(x<=mid)res+=queryrank(ls,l,mid,x,y,k);
	if(y>mid)res+=queryrank(rs,mid+1,r,x,y,k);
	return res;
}
long long querykth(int x,int y,long long k) {
	long long l=-inf,r=inf;
	while(r-l>1) {
		long long mid=(l+r)/2;
		long long rk=queryrank(1,1,n,x,y,mid)+1;
		if(rk<=k)r=mid;
		else l=mid;
	}
	return r;
}
int main() {
	scanf("%d%d",&n,&m);
	while(m--) {
		int op,a,b;
		long long c;
		scanf("%d%d%d%lld",&op,&a,&b,&c);
		if(op==1)update(1,1,n,a,b,c);
		else printf("%lld\n",querykth(a,b,c));
	}
	return 0;
}
2021/7/1 11:11
加载中...