莫队 + Treap 80pts RE 后两个点求助
查看原帖
莫队 + Treap 80pts RE 后两个点求助
759710
LuoFeng_Nanami楼主2023/10/17 19:58
#include<bits/stdc++.h>
#define ll long long
#define rll register ll
#define F(i,a,b) for(rll i=a;i<=b;i++)
#define Fdn(i,a,b) for(rll i=a;i>=b;i--)
#define int ll
#define itn int
#define Sort sort(a + 1,a + n + 1)
#define SortCmp sort(a + 1,a + n + 1,cmp)
#define R(n) n = read()
#define Bk break
#define Pc putchar

using namespace std;
namespace IO{
	char ibuf[(1<<20)+1],*iS,*iT;
	#if ONLINE_JUDGE
	#define gh() (iS==iT?iT=(iS=ibuf)+fread(ibuf,1,(1<<20)+1,stdin),(iS==iT?EOF:*iS++):*iS++)
 	#else
	#define gh() getchar()
	#endif
	#define reg register
	inline ll read(){
		reg char ch=gh();
		reg ll x=0;
		reg char t=0;
		while(ch<'0'||ch>'9')   t|=ch=='-',ch=gh();
		while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=gh();
		return t?-x:x;
	}
	inline void writ(ll x)
	{
		if(x < 0){
			putchar('-');
			x = -x;
		}
		if(x > 9) 
			writ(x / 10);
		putchar(x % 10 + '0');
	}
	inline void write(ll x,char c)
	{
		writ(x);
		putchar(c);
	}
}
using IO::read;
using IO::writ;
using IO::write;
#define umap unordered_map
#define uset unordered_set
#define ld long double
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pb push_back
const ll ll_INF=9223372036854775807;
namespace mySTL{
	inline ll max(ll a,ll b){return a>b?a:b;}
	inline ll min(ll a,ll b){return a<b?a:b;}
	inline ld min(ld a,ld b){return a<b?a:b;}
	inline ld max(ld a,ld b){return a>b?a:b;}
	inline void swap(ll &a,ll &b){a^=b,b^=a,a^=b;}
	inline ll pw(ll a,ll b,ll p){if(b==0)return 1;
	if(b==1)return a%p;
	ll mid=pw(a,b/2,p)%p;
	if(b&1)return mid*mid%p*a%p;else{return mid*mid%p;}}
	inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
	inline ll lcm(ll a,ll b){return a*b/gcd(a,b);}
}
using namespace mySTL;

const int inf = 0x3f3f3f3f,mod = 1e9 + 7; 
const int maxn = 3e5 + 7;
const int INF = 0x7fffffff;

struct Treap{
	int l,r;
	int val,dat;
	int cnt,size;
}a[maxn];

struct query{
	int l, r, k, id;
}q[maxn];

int tot, root, n, m; 
int num[maxn];
int yousa[maxn];
int mx;

inline int Add(int val){
	a[++tot].val = val;
	a[tot].dat = rand();
	a[tot].cnt = a[tot].size = 1;
	return tot;
}

inline void Update(int p){
	a[p].size = a[a[p].l].size + a[a[p].r].size + a[p].cnt;
}

inline void Build(){
	Add(-ll_INF),Add(ll_INF);
	root = 1,a[1].r = 2;
	Update(root);
}

inline int GetRankByVal(int p,int val){
	if(p == 0)
		return 1;
	if(val == a[p].val)
		return a[a[p].l].size + 1;
	if(val < a[p].val)
		return GetRankByVal(a[p].l,val);
	return GetRankByVal(a[p].r,val) + a[a[p].l].size + a[p].cnt;
}

inline int GetValByRank(int p,int rank){
	if(p == 0)
		return INF;
	if(a[a[p].l].size >= rank)
		return GetValByRank(a[p].l,rank);
	if(a[a[p].l].size + a[p].cnt >= rank)
		return a[p].val;
	return GetValByRank(a[p].r,rank - a[p].cnt - a[a[p].l].size);
}

inline void zig(int &p){
	int q = a[p].l;
	a[p].l = a[q].r,a[q].r = p,p = q;// changed
	Update(a[p].r),Update(p);
}

inline void zag(int &p){
	int q = a[p].r;
	a[p].r = a[q].l,a[q].l = p,p = q;// changed
	Update(a[p].l),Update(p);
}

inline void Insert(int &p,int val){
	if(p == 0){
		p = Add(val);
		return;
	}
	if(val == a[p].val){
		a[p].cnt++,Update(p);
		return;
	}
	if(val < a[p].val){
		Insert(a[p].l,val);
		if(a[p].dat < a[a[p].l].dat)
			zig(p);
	}
	else{
		Insert(a[p].r,val);
		if(a[p].dat < a[a[p].r].dat)
			zag(p);
	}
	Update(p);
}

inline void Remove(int &p,int val){
	if(p == 0)
		return;
	if(val == a[p].val){
		if(a[p].cnt > 1){
			a[p].cnt--,Update(p);
			return;
		}
		if(a[p].l || a[p].r){
			if(!a[p].r || a[a[p].l].dat > a[a[p].r].dat)// ques
				zig(p),Remove(a[p].r,val);
			else
				zag(p),Remove(a[p].l,val); 
			Update(p);
		}
		else
			p = 0;
		return;
	}
	val < a[p].val ? Remove(a[p].l,val) : Remove(a[p].r,val);
	Update(p);
}

inline int GetPre(int val){
	int ans = 1;// a[1].val = INF
	int p = root;
	while(p){
		if(val == a[p].val){
			if(a[p].l > 0){
				p = a[p].l;
				while(a[p].r > 0)
					p = a[p].r;
				ans = p;
			}
			break;
		}
		if(a[p].val < val && a[p].val > a[ans].val)
			ans = p;
		p = val < a[p].val ? a[p].l : a[p].r;
	}
	return a[ans].val;
}

inline int GetNext(int val){
	int ans = 2;
	int p = root;
	while(p){
		if(val == a[p].val){
			if(a[p].r > 0){
				p = a[p].r;
				while(a[p].l > 0)
					p = a[p].l;
				ans = p; 
			}
			break;
		}
		if(a[p].val > val && a[p].val < a[ans].val)
			ans = p;
		p = val < a[p].val ? a[p].l : a[p].r;
	}
	return a[ans].val;
}

inline bool cmp(query a, query b){ 
	if(a.l / mx != b.l / mx) return a.l < b.l;
	return (a.l / mx) & 1 ? a.r < b.r : a.r > b.r;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	srand(time(0));
	Build();
	R(n), R(m);
	mx = sqrt(n);
	F(i, 1, n)
		R(num[i]);
	F(i, 0, m - 1)
		R(q[i].l), R(q[i].r), R(q[i].k), q[i].id = i;
	sort(q, q + m, cmp);
	int l = 1, r = 0;
	F(i, 0, m - 1){
		while(l > q[i].l) Insert(root, num[--l]);
		while(r < q[i].r) Insert(root, num[++r]);
		while(l < q[i].l) Remove(root, num[l++]);
		while(r > q[i].r) Remove(root, num[r--]);
		yousa[q[i].id] = GetValByRank(root, q[i].k + 1);
	}
	F(i, 0, m - 1)
		write(yousa[i], '\n');
	
	return 0;
}
2023/10/17 19:58
加载中...