记录编号 538093 评测结果 AAAAAAAAAA
题目名称 [TYVJ1730]二逼平衡树 最终得分 100
用户昵称 GravatarHale 是否通过 通过
代码语言 C++ 运行时间 5.402 s
提交时间 2019-07-21 21:49:59 内存使用 67.07 MiB
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
const int M=2e6+7;
const int INF=0x7f7f7f7f;
int m,n,k,p,cnt;
int l[M],r[M],pri[M],sz[M],v[M],a[M];
int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
struct FHQ_treap
{
	int root,x,y,z;
	int new_node(int a) {cnt++;sz[cnt]=1;v[cnt]=a;pri[cnt]=rand();return cnt;}
	void push_up(int x) {sz[x]=sz[l[x]]+sz[r[x]]+1;}
	int merge(int x,int y)
	{
		if (!x||!y) return x+y;
		if (pri[x]<pri[y]) {r[x]=merge(r[x],y);push_up(x);return x;}
		else {l[y]=merge(x,l[y]);push_up(y);return y;}
	}
	void split(int now,int k,int &x,int &y)
	{
		if (!now) x=0,y=0;
		else 
		{
			if (v[now]<=k) x=now,split(r[now],k,r[x],y);
			else y=now,split(l[now],k,x,l[y]);
			push_up(now);
		}
	}
	void insert(int a) {split(root,a,x,y);root=merge(merge(x,new_node(a)),y);}
	void Delete(int a) {split(root,a,x,z);split(x,a-1,x,y);y=merge(l[y],r[y]);root=merge(merge(x,y),z);}
	int K_th(int now,int k)
	{
		while (true)
		{
			if (sz[l[now]]>=k) now=l[now];
			else if (k==sz[l[now]]+1) return now;
			else k-=sz[l[now]]+1,now=r[now];
		}
	}
	int Rank(int a) {split(root,a-1,x,y);int ans=sz[x]+1;root=merge(x,y);return ans;}
	int upper(int a) {split(root,a,x,y);int ans=sz[y]?v[K_th(y,1)]:INF;root=merge(x,y);return ans;}
	int lower(int a) {split(root,a-1,x,y);int ans=sz[x]?v[K_th(x,sz[x])]:-INF;root=merge(x,y);return ans;}
	void build(int x,int y) {for (int i=x;i<=y;i++) insert(a[i]);} 
} FT[N<<2];
#define ls (p<<1)
#define rs (p<<1|1)
#define mid ((l+r)>>1)
struct segment_tree
{
	int root[N<<2];
	void build(int l,int r,int p)
	{
		FT[p].build(l,r);
		if (l!=r) build(l,mid,ls),build(mid+1,r,rs);
	}
	int Q_Rank(int nl,int nr,int p,int l,int r,int val)
	{
		if (r<nl||l>nr) return 0;
		if (nl<=l&&r<=nr) return FT[p].Rank(val)-1;
		return Q_Rank(nl,nr,ls,l,mid,val)+Q_Rank(nl,nr,rs,mid+1,r,val);
	}
	int Q_val(int l,int r,int rak)
	{
		int x=0,y=1e8,ans=-1;
		while (x<=y)
		{
			int M=(x+y)>>1;
			if (Q_Rank(l,r,1,1,n,M)+1<=rak) ans=M,x=M+1;
			else y=M-1;
		}
		return ans;
	}
	void update(int l,int r,int p,int pos,int val)
	{
		FT[p].Delete(a[pos]);
		FT[p].insert(val);
		if (l!=r)
		{
			if (pos<=mid) update(l,mid,ls,pos,val);
			else update(mid+1,r,rs,pos,val);
		}
	}
	int Lower(int nl,int nr,int p,int l,int r,int val)
	{
		if (nr<l||r<nl) return -INF;
		if (nl<=l&&r<=nr) return FT[p].lower(val);
		return max(Lower(nl,nr,ls,l,mid,val),Lower(nl,nr,rs,mid+1,r,val));
	}
	int Upper(int nl,int nr,int p,int l,int r,int val)
	{
		if (nr<l||r<nl) return INF;
		if (nl<=l&&r<=nr) return FT[p].upper(val);
		return min(Upper(nl,nr,ls,l,mid,val),Upper(nl,nr,rs,mid+1,r,val));
	}
} ST;
int main()
{
	freopen("psh.in","r",stdin);
	freopen("psh.out","w",stdout);
	srand((unsigned)time(NULL));
	n=read();int Q=read();
	for (int i=1;i<=n;i++) a[i]=read();
	ST.build(1,n,1);
	int opt,l,r,val,pos,k;
	while (Q--)
	{
		opt=read();
		if (opt==1) {l=read(),r=read(),val=read();printf("%d\n",ST.Q_Rank(l,r,1,1,n,val)+1);}
		else if (opt==2) {l=read(),r=read(),k=read();printf("%d\n",ST.Q_val(l,r,k));}
		else if (opt==3) {pos=read();val=read();ST.update(1,n,1,pos,val);a[pos]=val;}
		else if (opt==4) {l=read(),r=read(),val=read();printf("%d\n",ST.Lower(l,r,1,1,n,val));}
		else if (opt==5) {l=read(),r=read(),val=read();printf("%d\n",ST.Upper(l,r,1,1,n,val));}
	}
	return 0;
}