40ptsTLE求调啊啊啊啊,慢出天际,1s只跑1000个操作
查看原帖
40ptsTLE求调啊啊啊啊,慢出天际,1s只跑1000个操作
555833
haozexu楼主2023/11/19 12:12

RT. 快优化到头了,不知道是不是假了,按第二篇题解的写法写的,就是外层权值,内层位置。

求大佬调,谢谢

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
const int LOG2N=log2(N)+2;
int n,m;
const int INF=2147483647;
//Unit FHQTreap
struct interval{
	int l,r;
	interval(){l=r=0;}
	interval(int ll,int rr){l=ll,r=rr;}
	inline int mid(){return (l+r)/2;}
	inline interval ls(){
		return interval(l,mid());
	}
	inline interval rs(){
		return interval(mid()+1,r);
	}
	inline bool isleaf(){
		return l==r;
	}
	inline bool contains(interval &o){
		return l<=o.l&&o.r<=r;
	}
};
inline interval global(){
	return interval(0,1e8);
}
namespace FHQ{
	mt19937 _rng(time(0));
	struct _{
		int ls,rs;
		int siz,val,rnd;
		_(){}
		_(int v){siz=1,val=v,rnd=(_rng)(),ls=rs=0;}
	}s[N*LOG2N*4];
	void Update(int p){
		s[p].siz=s[s[p].ls].siz+s[s[p].rs].siz+1;
	}
	int tot;
	int Alloc(int val){
		int id=++tot;
		s[id]=_(val);
		return id;
	}
	void SplitByVal(int p,int &x,int &y,int val){
		if(!p){
			x=y=0;
			return;
		}
		if(s[p].val<=val){
			x=p,SplitByVal(s[p].rs,s[p].rs,y,val);
		}else{
			y=p,SplitByVal(s[p].ls,x,s[p].ls,val);
		}
		Update(p);
	}
	int Merge(int x,int y){
		if(!x||!y) return x+y;
		if(s[x].rnd>s[y].rnd){
			s[x].rs=Merge(s[x].rs,y);
			Update(x);
			return x;
		}else{
			s[y].ls=Merge(x,s[y].ls);
			Update(y);
			return y;
		}
	}
	class FHQTreap{
	public:
		int root;
		FHQTreap(){
			root=0;
		}
		void Insert(int v){
			int t1,t2;//all is well
			SplitByVal(root,t1,t2,v);
			root=Merge(Merge(t1,Alloc(v)),t2);
		}
		void Delete(int v){
			int t1,t2,t3;
			SplitByVal(root,t1,t3,v);
			SplitByVal(t1,t1,t2,v-1);
			root=Merge(t1,t3);
		}
		void P(int p,int &ans,int v){
			if(!p) return;
			if(s[p].val<=v){
				ans+=s[s[p].ls].siz+1;
				P(s[p].rs,ans,v);
			}else{
				P(s[p].ls,ans,v);
			}
		}
		int Query(interval &q){
			int l=q.l,r=q.r;
			int ans1=0,ans2=0;
			P(root,ans1,r),P(root,ans2,l-1);
			return ans1-ans2;
		}
	};	
}
namespace SEG{
	//Unit SegmentTree
	struct _{
		int ls,rs;
		FHQ::FHQTreap fhq;
		_(){
			ls=rs=0;
		}
	}s[N*LOG2N];
	int tot;
	int Alloc(){
		int id=++tot;
		s[id]=_();
		return id;
	}
	class SegmentTree{
	public:
		int root;
		SegmentTree(){
			root=0;
		}
		void Insert(int &p,interval t,int val,int x){//Actually insert x...
			if(!p) p=Alloc();
			s[p].fhq.Insert(x);
			if(t.isleaf()) return;
			int mid=t.mid();
			if(val<=mid) Insert(s[p].ls,t.ls(),val,x);
			else		 Insert(s[p].rs,t.rs(),val,x);
		}
		void Remove(int &p,interval t,int val,int x){//Actually remove x...
			if(!p) return;
			s[p].fhq.Delete(x);
			if(t.isleaf()){
				return;
			}
			int mid=t.mid();
			if(val<=mid) Remove(s[p].ls,t.ls(),val,x);
			else	     Remove(s[p].rs,t.rs(),val,x);
		}
		interval q,r;
		int Rank(int p,interval t){
			if(!p) return 0;
			if(q.contains(t)) return s[p].fhq.Query(r);
			int mid=t.mid(),res=0;
			if(q.l<=mid) res+=Rank(s[p].ls,t.ls());
			if(q.r>mid)  res+=Rank(s[p].rs,t.rs());
			return res;
		}
		int Value(int p,interval t,int k){
			if(!p) return -INF;
			if(t.isleaf()) return t.l;
			int res=s[s[p].ls].fhq.Query(r);
			if(k>res) return Value(s[p].rs,t.rs(),k-res);
			else	   return Value(s[p].ls,t.ls(),k);
		}
		int Prev(int p,interval t){
			if(!p) return -INF;
			if(s[p].fhq.Query(r)==0) return -INF;
			if(t.isleaf()) return t.l;
			int mid=t.mid(),res=-INF;
			if(q.l<=mid) res=max(res,Prev(s[p].ls,t.ls()));
			if(q.r>mid)  res=max(res,Prev(s[p].rs,t.rs()));
			return res;
		}
		int Next(int p,interval t){
			if(!p) return INF;
			if(s[p].fhq.Query(r)==0) return INF;
			if(t.isleaf()) return t.l;
			int mid=t.mid(),res=INF;
			if(q.l<=mid) res=min(res,Next(s[p].ls,t.ls()));
			if(q.r>mid)  res=min(res,Next(s[p].rs,t.rs()));
			return res;
		}
		void Modify(int x,int k,int ori){
			Remove(root,global(),ori,x);
			Insert(root,global(),k,x);
		}
	};	
}
inline int read(){
	register int w=0,x=0;char ch;
	while(ch<'0'||ch>'9'){w|=ch=='-';ch=getchar();}
	while('0'<=ch&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return w?-x:x;
}
SEG::SegmentTree seg;
int a[N];
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
		seg.Insert(seg.root,global(),a[i],i);
	}
	while(m--){
		int op,l,r,k;
		op=read(),l=read(),r=read();
		if(op!=3) k=read();
		switch(op){
			case 1:{
				seg.q=interval(0,k-1),seg.r=interval(l,r);
				printf("%d\n",seg.Rank(seg.root,global())+1);
				break;
			}
			case 2:{
				seg.r=interval(l,r);
				printf("%d\n",seg.Value(seg.root,global(),k));
				break;
			}
			case 3:{
				seg.Modify(l,r,a[l]);
				a[l]=r;
				break;
			}
			case 4:{
				seg.q=interval(0,k-1),seg.r=interval(l,r);
				printf("%d\n",seg.Prev(seg.root,global()));
				break;
			}
			case 5:{
				seg.q=interval(k+1,1e8),seg.r=interval(l,r);
				printf("%d\n",seg.Next(seg.root,global()));
				break;
			}
		}
	}
	
}
2023/11/19 12:12
加载中...