Description
Wind loves pretty dogs very much, and she has n pet dogs. So Jiajia has to feed the dogs every day for Wind. Jiajia loves Wind, but not the dogs, so Jiajia use a special way to feed the dogs. At lunchtime, the dogs will stand on one line, numbered from 1 to n, the leftmost one is 1, the second one is 2, and so on. In each feeding, Jiajia choose an inteval[i,j], select the k-th pretty dog to feed. Of course Jiajia has his own way of deciding the pretty value of each dog. It should be noted that Jiajia do not want to feed any position too much, because it may cause some death of dogs. If so, Wind will be angry and the aftereffect will be serious. Hence any feeding inteval will not contain another completely, though the intervals may intersect with each other.
Your task is to help Jiajia calculate which dog ate the food after each feeding.
解题思路
题目意思大致就是给出一个序列,每次询问区间[i,j]的第k大的数,并且询问的区间不会重叠或覆盖
如果没有最后这个条件,那么这题就需要用线段树套Treap来做,那么最后这个条件有什么用?显然,题目在提示我们用离线算法,因为最后这个性质只在离线算法里有用,可以把线段排序,这样,每次Treap中存的都是前一条线段,而线段不会重叠或覆盖,这样,要使Treap中存的是当前的线段,只要从前一条线段的尾部删去不在当前线段中的元素,然后加上当前线段尾部不在前一条线段中的元素。最后注意输出要按照输入顺序。
附上代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define maxn 100006
#define maxm 50006
using namespace std;
struct node{
node* ch[2];
int key,f,s,num;
void maintain(){
s=num;
if(ch[0]!=NULL)s+=ch[0]->s;
if(ch[1]!=NULL)s+=ch[1]->s;
}
}treap[maxn];
typedef node* pnode;
node nul;
pnode root,len,null=&nul;
void rot(pnode &p,int d){
pnode k=p->ch[d^1];p->ch[d^1]=k->ch[d];k->ch[d]=p;
p->maintain();k->maintain();p=k;
}
pnode newnode(int key){
len->ch[0]=len->ch[1]=null;len->key=key;len->s=len->num=1;len->f=rand();
return len++;
}
void insert(pnode &p,int x){
if(p==null)p=newnode(x);else
if(p->key==x)p->s++,p->num++;else{
int d=p->key<x;
insert(p->ch[d],x);
if(p->ch[d]->f<p->f)rot(p,d^1);
}
p->maintain();
}
void erase(pnode &p,int x){
if(p->key==x){
if(p->num>1)p->num--;else
if(p->ch[0]==null)p=p->ch[1];else
if(p->ch[1]==null)p=p->ch[0];else{
int d=p->ch[0]->f>p->ch[1]->f;
rot(p,d^1);
erase(p->ch[d^1],x);
}
}else{
int d=p->key<x;
erase(p->ch[d],x);
}
p->maintain();
}
int getn(pnode p,int x){
if(p->ch[0]->s+1<=x&&p->ch[0]->s+p->num>=x)return p->key;else
if(p->ch[0]->s>=x)return getn(p->ch[0],x);else
return getn(p->ch[1],x-p->ch[0]->s-p->num);
}
void print(pnode p){
if(p==null)return;
print(p->ch[0]);
for(int i=1;i<=p->num;i++) printf("%d ",p->key);
print(p->ch[1]);
}
struct data{
int s,t,k,id,ans;
}b[maxm];
int n,m,a[maxn];
bool cmp_s(const data x,const data y){
return x.s<y.s;
}
bool cmp_id(const data x,const data y){
return x.id<y.id;
}
int main(){
freopen("feedog.in","r",stdin);
freopen("feedog.out","w",stdout);
len=treap;root=null;null->ch[0]=null->ch[1]=null;null->s=null->num=0;
// scanf("%d",&n);
// for(int i=1;i<=n;i++){
// int x,y;
// scanf("%d%d",&x,&y);
// if(x==1)insert(root,y);else
// if(x==2)erase(root,y);else
// printf("%d\n",getn(root,y));
// printf("Treap=");print(root);printf("\n");
// }
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&b[i].s,&b[i].t,&b[i].k);
if(b[i].s>b[i].t)swap(b[i].s,b[i].t);
b[i].id=i;
}
sort(b+1,b+1+m,cmp_s);b[0].s=1e9;b[0].t=-1e9;
for(int i=1;i<=m;i++){
int s=min(b[i-1].t,b[i].s-1),t=max(b[i-1].t+1,b[i].s);
for(int j=b[i-1].s;j<=s;j++)erase(root,a[j]);
for(int j=t;j<=b[i].t;j++)insert(root,a[j]);
b[i].ans=getn(root,b[i].k);
// printf("%d %d\n",b[i].s,b[i].t);
// printf("Treap=");print(root);printf("\n");
}
sort(b+1,b+1+m,cmp_id);
for(int i=1;i<=m;i++) printf("%d\n",b[i].ans);
return 0;
}