线段树套FHQ,80分,O2全MLE
查看原帖
线段树套FHQ,80分,O2全MLE
579857
popossible楼主2023/10/17 21:44

rt,只是想问一问为什么开O2后全MLE

#include<bits/stdc++.h>
using namespace std;

const int MAX=int(2e5)+1;

struct node{
	int dat,siz,son[2],ord;
	node(int _d=0,int _s=0,int _s1=0,int _s2=0,int _o=0):
		dat(_d),siz(_s),ord(_o){son[0]=_s1,son[1]=_s2;}
};

struct FHQ_TREAP{
	friend node;
	vector<node >tr;
	int tot,rt;
	queue<int>trash;
	
	void init(int l,int r){
		tr.resize(r-l+2);
	}
	
	#define da(x) tr[x].dat
	#define si(x) tr[x].siz
	#define ls(x) tr[x].son[0]
	#define rs(x) tr[x].son[1]
	#define o(x) tr[x].ord
	
	void delnode(int now){
		tr[now]=node();
		trash.push(now);
	}
	
	int getnode(){
		if(trash.empty()) return ++tot;
		int now=trash.front();
		trash.pop();
		return now;
	}
	
	int newnode(int d){
		int now=getnode();
		tr[now]=node(d,1,0,0,rand());
		return now;
	}
	
	void pushup(int now){
		si(now)=si(ls(now))+si(rs(now))+1;
	}
	
	void split(int now,int d,int &x,int &y){
		if(!now) {x=y=0;return;}
		if(da(now)<=d) {x=now;split(rs(x),d,rs(x),y);}
		else {y=now;split(ls(y),d,x,ls(y));}
		pushup(now);
	}
	
	int merge(int x,int y){
		if(!x||!y) return x|y;
		if(o(x)<o(y)) {rs(x)=merge(rs(x),y);pushup(x);return x;}
		else {ls(y)=merge(x,ls(y));pushup(y);return y;}
	}
	
	void insert(int d){
		int x=0,y=0;
		split(rt,d,x,y);
		rt=merge(merge(x,newnode(d)),y);
	}
	
	void del(int d){
		int x=0,y=0,z=0;
		split(rt,d,x,z);
		split(x,d-1,x,y);
		int now=y;
		y=merge(ls(y),rs(y));
		if(now) delnode(now);
		rt=merge(merge(x,y),z);
	}
	
	int getrank(int d){
		int x=0,y=0;
		split(rt,d-1,x,y);
		int res=si(x);
		rt=merge(x,y);
		return res;
	}
	
	int getrankx(int k){
		int now=rt;
		while(1){
			if(si(ls(now))>=k) now=ls(now);
			else{
				if(k<=si(ls(now))+1) return da(now);
				k-=ls(now)+1;now=rs(now);
			}
		}
	}
	
	int getfront(int d){
		int x=0,y=0;
		split(rt,d-1,x,y);
		if(!x) return INT_MIN+1;
		int now=x;
		while(rs(now)) now=rs(now);
		int res=da(now);
		rt=merge(x,y);
		return res; 
	}
	
	int getback(int d){
		int x=0,y=0;
		split(rt,d,x,y);
		if(!y) return INT_MAX;
		int now=y;
		while(ls(now)) now=ls(now);
		int res=da(now);
		rt=merge(x,y);
		return res; 
	}
	
	void print(int now){
		if(ls(now)) print(ls(now));
		cout<<da(now)<<" ";
		if(rs(now)) print(rs(now));
	}
}fhq_treap[MAX];

int n,m,a[MAX],res,sgn;

void print(int now,int l,int r){
	cout<<l<<" "<<r<<"\n";
	fhq_treap[now].print(fhq_treap[now].rt);
	cout<<"\n";
	if(l==r) return ;
	int mid=l+r>>1;
	print(now<<1,l,mid);print(now<<1|1,mid+1,r);
}

void build(int now,int l,int r){
	fhq_treap[now].init(l,r);
	for(int i=l;i<=r;i++) fhq_treap[now].insert(a[i]); 
	if(l==r) return;
	int mid=l+r>>1;
	build(now<<1,l,mid);build(now<<1|1,mid+1,r);
}

void update(int now,int l,int r,int aim,int old,int to){
	fhq_treap[now].del(old);
	fhq_treap[now].insert(to);
	if(l==r) return;
	int mid=l+r>>1;
	if(mid>=aim) update(now<<1,l,mid,aim,old,to);
	else update(now<<1|1,mid+1,r,aim,old,to);
}

int queryrank(int now,int l,int r,int L,int R,int d){
	if(l>R||r<L) return 0;
	if(L<=l&&r<=R) return fhq_treap[now].getrank(d);
	int mid=l+r>>1;
	return queryrank(now<<1,l,mid,L,R,d)+queryrank(now<<1|1,mid+1,r,L,R,d);
} 

int queryrankx(int L,int R,int k){
	int l=0,r=(int)1e8,ans=0;
	while(l<=r){
		int mid=(l+r)>>1;
		if(queryrank(1,1,n,L,R,mid)+1<=k){
			ans=mid,l=mid+1;
		}
		else r=mid-1;
	}
	return ans;
}

int queryfront(int now,int l,int r,int L,int R,int d){
	if(l>R||r<L) return INT_MIN+1;
	if(L<=l&&r<=R) return fhq_treap[now].getfront(d);
	int mid=l+r>>1;
	return max(queryfront(now<<1,l,mid,L,R,d),queryfront(now<<1|1,mid+1,r,L,R,d));
} 

int queryback(int now,int l,int r,int L,int R,int d){
	if(l>R||r<L) return INT_MAX;
	if(L<=l&&r<=R) return fhq_treap[now].getback(d);
	int mid=l+r>>1;
	return min(queryback(now<<1,l,mid,L,R,d),queryback(now<<1|1,mid+1,r,L,R,d));
} 

inline int read(){
	res=0,sgn=0;
	char ch=getchar();
	while(!isdigit(ch)) sgn|=ch=='-'?1:0,ch=getchar();
	while(isdigit(ch)) res=res*10+ch-'0',ch=getchar();
	return sgn?-res:res;
}

inline int put(int num){
	if(num/10) put(num/10);
	putchar(num%10+'0');
}

int main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0),cout.tie(0);
	n=read(),m=read();
	for(int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt=read();
		if(opt==1){
			int l=read(),r=read(),d=read();
			put(queryrank(1,1,n,l,r,d)+1),putchar('\n');
			continue;
		}
		if(opt==2){
			int l=read(),r=read(),k=read();
			put(queryrankx(l,r,k)),putchar('\n');
			continue;
		}
		if(opt==3){
			int pos=read(),x=read();
			update(1,1,n,pos,a[pos],x);
			a[pos]=x;
			continue;
		}
		if(opt==4){
			int l=read(),r=read(),d=read(),res=queryfront(1,1,n,l,r,d);
			if(res<0) putchar('-'),res=-res;
			put(res),putchar('\n');
			continue;
		}
		int l=read(),r=read(),d=read();
		put(queryback(1,1,n,l,r,d)),putchar('\n');
	}
	return 0;
}
2023/10/17 21:44
加载中...