#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 100005
#define maxm 50005
int ls[maxn],rs[maxn],s[maxn],value[maxn];
int node,root;
void init()
{
node=root=s[0]=0;
}
void Right_Rotate(int &t)
{
int k=ls[t];
ls[t]=rs[k];
rs[k]=t;
s[k]=s[t];
s[t]=s[ls[t]]+s[rs[t]]+1;
t=k;
}
void Left_Rotate(int &t)
{
int k=rs[t];
rs[t]=ls[k];
ls[k]=t;
s[k]=s[t];
s[t]=s[ls[t]]+s[rs[t]]+1;
t=k;
}
void Maintain(int &t,bool flag)
{
if(flag)
if(s[rs[rs[t]]]>s[ls[t]])
Left_Rotate(t);
else if(s[ls[rs[t]]]>s[ls[t]])
Right_Rotate(rs[t]),Left_Rotate(t);
else return ;
else if(s[ls[ls[t]]]>s[rs[t]])
Right_Rotate(t);
else if(s[rs[ls[t]]]>s[rs[t]])
Left_Rotate(ls[t]),Right_Rotate(t);
else return ;
Maintain(ls[t],0);
Maintain(rs[t],1);
Maintain(t,0);
Maintain(t,1);
}
void Insert(int &t,int val) //将键值为v的结点插入到根为t的树中
{
if(t)
{
++s[t];
if(val<value[t]) Insert(ls[t],val);
else Insert(rs[t],val);
Maintain(t,val>=value[t]);
}
else
{
s[t=++node]=1;
value[t]=val;
ls[t]=rs[t]=0;
}
}
int Delete(int &t,int val) //在根为t的树中删除键值为v的结点
{
--s[t];
if(val==value[t]||val<value[t]&&!ls[t]||val>value[t]&&!rs[t])
{
int tmp=value[t];
if(!ls[t]||!rs[t]) t=ls[t]+rs[t];
else value[t]=Delete(ls[t],value[t]+1);
return tmp;
}
else
if(val<value[t]) return Delete(ls[t],val);
else return Delete(rs[t],val);
}
int Pred(int t,int val) //返回根为t的树中比v小的最大的键值
{
if(!t) return val;
if(val<=value[t]) return Pred(ls[t],val);
else
{
int tmp=Pred(rs[t],val);
return tmp==val?value[t]:tmp;
}
}
int Succ(int t,int val) //返回根为t的树中比v大的最小的键值
{
if(!t) return val;
if(val>=value[t]) return Succ(rs[t],val);
else
{
int tmp=Succ(ls[t],val);
return tmp==val?value[t]:tmp;
}
}
int Find(int t,int val) //在根为t的树中查找键值为v的结点
{
while(t&&val!=value[t])
t=val<value[t]?Find(ls[t],val):Find(rs[t],val);
return t;
}
int Rank(int t,int val) //返回根为t的树中键值v的排名。也就是树中键值比v小的结点数+1
{
if(!t) return 1;
if(val<=value[t]) return Rank(ls[t],val);
else return s[ls[t]]+1+Rank(rs[t],val);
}
int Select(int t,int k) //返回根为t的树中排名为k的结点。
//同时该操作能够实现Get-min,Get-max,因为Get-min等于Select(t,1),Get-max等于Select(t,s[t])
{
if(k==s[ls[t]]+1) return value[t];
if(k<=s[ls[t]]) return Select(ls[t],k);
else return Select(rs[t],k-1-s[ls[t]]);
}
void Debug(int t)
{
if(!t)
{
puts("empty!");
return ;
}
if(ls[t])
Debug(ls[t]);
printf("%d ",value[t]);
if(rs[t])
Debug(rs[t]);
}
struct qnode
{
int l,r,k,id;
bool operator < (const qnode &tmp) const
{
return l<tmp.l;
}
} q[maxm];
int a[maxn],ans[maxm],mp[maxn];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
init();
for(int i=1; i<=n; i++)
scanf("%d",a+i);
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
q[i].id=i;
}
sort(q+1,q+1+m);
q[0].l=0,q[0].r=0;
for(int i=1; i<=m; i++)
{
for(int j=q[i-1].l; j<=q[i-1].r&&j<q[i].l; j++)
if(j==0) continue;
else Delete(root,a[j]);
//Debug(root);
for(int j=q[i-1].r>=q[i].l?q[i-1].r+1:q[i].l; j<=q[i].r; j++)
{
Insert(root,a[j]);
//Debug(root);
}
ans[q[i].id]=Select(root,q[i].k);
}
for(int i=1; i<=m; i++)
printf("%d\n",ans[i]);
return 0;
}
POJ 2761 (SBT模板)
最新推荐文章于 2018-10-17 19:55:00 发布