X姐推荐做的一道喂狗题= =,的确是挺有想法的一道题。
其实就是treap模板题,注意两个地方,一是数据有重复(WA无数次出的结论),二是必须离线处理查询。
(据说用树状数组和线段树也能A)
第一次理解到原来离线处理作用这么大,具体来说就是对所有查询根据起点和终点排序,由于题目保证了所有查询不相互包含,所以从左向右,每次删除多余的,添加进新来的,然后执行查询操作,保存答案。
Treap真厉害啊,贴个WLJ的模板= =
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <climits>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <stack>
#include <deque>
#include <algorithm>
using namespace std;
const int INF=~0U>>1;
class treap
{
struct node
{
node* c[2];
int value,key,size;
node(int v,node* n):value(v)
{c[0]=c[1]=n;size=1;key=rand()-1;}
void rz(){size=c[0]->size+c[1]->size+1;}
}*root,*null;
void rot(node* &t,bool d)
{
node*c=t->c[d];
t->c[d]=c->c[!d];
c->c[!d]=t;
t->rz();c->rz();
t=c;
}
void insert(node* &t,int x)
{
if(t==null) {t=new node(x,null);return;}
// if(x==t->value) return;
bool d=x>t->value;
insert(t->c[d],x);
if(t->c[d]->key<t->key)
rot(t,d);
else
t->rz();
}
void Delete(node* &t,int x)
{
if(t==null) return;
if(t->value==x)
{
bool d=t->c[1]->key<t->c[0]->key;
if(t->c[d]==null)
{
delete t;
t=null;
return;
}
rot(t,d);
Delete(t->c[!d],x);
}
else
{
bool d=x>t->value;
Delete(t->c[d],x);
}
t->rz();
}
int select(node* t,int k)
{
int r=t->c[0]->size;
if(k==r) return t->value;
if(k<r) return select(t->c[0],k);
return select(t->c[1],k-r-1);
}
int rank(node*t,int x)
{
if(t==null) return 0;
int r=t->c[0]->size;
if(x==t->value) return r;
if(x<t->value) return rank(t->c[0],x);
return r+1+rank(t->c[1],x);
}
public:
treap()
{
null=new node(0,0);null->size=0;null->key=INF;
root=null;
}
void ins(int x)
{
insert(root,x);
}
int sel(int k)
{
if(k>root->size) return -INF;
return select(root,k-1);
}
int ran(int x)
{
return rank(root,x);
}
void del(int x)
{
Delete(root,x);
}
}T;
const int maxn = 100010;
const int maxm = 50010;
int n,m,st,ed;
int p[maxn];
struct Feed
{
int id;
int a,b,c;
bool operator<(const Feed &o) const
{
return (a==o.a&&b<o.b) || a<o.a;
}
}feed[maxm];
int ans[maxm];
int main()
{
int i;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++) scanf("%d",&p[i]);
for (i=1;i<=m;i++) scanf("%d%d%d",&feed[i].a,&feed[i].b,&feed[i].c), feed[i].id=i;
sort(feed+1,feed+m+1);
st=ed=i=0;
while (++i<=m)
{
if (feed[i].a>ed)
{
T=treap();
st=feed[i].a; ed=feed[i].b;
for (int j=st;j<=ed;j++) T.ins(p[j]);
}
else
{
for (int j=st;j<feed[i].a;j++) T.del(p[j]);
for (int j=ed+1;j<=feed[i].b;j++) T.ins(p[j]);
st=feed[i].a; ed=feed[i].b;
}
ans[feed[i].id]=T.sel(feed[i].c);
}
for (i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}