P1533 可怜的狗狗
题意:
小卡家有N只狗,由于品种、年龄不同,每一只狗都有一个不同的漂亮值;
漂亮值与漂亮的程度成反比(漂亮值越低越漂亮),吃饭时,狗狗们会
按顺序站成一排等着主人给食物。可是嘉嘉真的很懒,他才不肯喂这么多狗呢,
这多浪费时间啊,于是他每次就只给第i只到第j只狗中第k漂亮的狗狗喂食(好
狠心的人啊).而且为了保证某一只狗狗不会被喂太多次,他喂的每个区间(i,j)不互相包含;
思路:因为要找的是排名第k的,考虑主席树和平衡树;
不会平衡树的点这里哦
由于刚学平衡树,这里提供平衡树思路,以为有很多区间,不可能
把上一次全删掉再一个一个加,T飞?
考虑莫队的思想,这题可以用莫队(不过我不会),可以把询问离线,拍下序,每次把
上下两次区间重复的就不用删除了,有大佬直接过了,可我常数大,不过吸个氧跑很快的;
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=3e5+7;
struct node{
int ff,val,siz,cnt,ch[2];
}t[N];
struct quary{
int l,r,k,id;
friend bool operator <(const quary &x,const quary &y){
return x.r<y.r;
}
}q[N<<1];
int n,m,tot,root;
int a[N],ans[N];
void up(int x){
t[x].siz=t[x].cnt+t[t[x].ch[0]].siz+t[t[x].ch[1]].siz;
}
void rotate(int x){
int y=t[x].ff;
int z=t[y].ff;
int k=t[y].ch[1]==x;
t[z].ch[t[z].ch[1]==y]=x;
t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];
t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;
t[y].ff=x;
up(y);up(x);
}
void splay(int x,int goal){
while(t[x].ff!=goal){
int y=t[x].ff,z=t[y].ff;
if(z!=goal) (t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y);
rotate(x);
}
if(goal==0) root=x;
}
void insert(int x){
int u=root,ff=0;
while(u&&t[u].val!=x){
ff=u;
u=t[u].ch[x>t[u].val];
}
if(u) t[u].cnt++;
else{
u=++tot;
if(ff) t[ff].ch[x>t[ff].val]=u;
t[u].siz=t[u].cnt=1;
t[u].ff=ff;
t[u].val=x;
}
splay(u,0);
}
void find(int x){
int u=root;
if(!u) return;
while(t[u].ch[x>t[u].val]&&t[u].val!=x){
u=t[u].ch[x>t[u].val];
}
splay(u,0);
}
int Nxt(int x,int f){
find(x);
int u=root;
if(x<t[u].val&&f) return u;
if(x>t[u].val&&!f) return u;
u=t[u].ch[f];
while(t[u].ch[f^1]) u=t[u].ch[f^1];
return u;
}
void Del(int x){
int last=Nxt(x,0);
int nxt=Nxt(x,1);
splay(last,0);
splay(nxt,last);
int del=t[nxt].ch[0];
if(t[del].cnt>1){
t[del].cnt--;
splay(del,0);
}else t[nxt].ch[0]=0,t[nxt].siz--,t[last].siz--;
}
int k_th(int x){
int u=root;
if(t[u].siz<x) return 0;
while(1){
int y=t[u].ch[0];
if(t[y].siz+t[u].cnt<x){
x-=t[y].siz+t[u].cnt;
u=t[u].ch[1];
}else{
if(x<=t[y].siz) u=y;
else return t[u].val;
}
}
}
int main(){
insert(-2147483647);
insert(2147483647);
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",&q[i].l,&q[i].r,&q[i].k);
q[i].id=i;
}
sort(q+1,q+m+1);
int x=q[1].l,y=q[1].r;
for(int i=q[1].l;i<=q[1].r;i++) insert(a[i]);
ans[q[1].id]=k_th(q[1].k+1);
for(int i=2;i<=m;i++){
while(x<q[i].l) Del(a[x]),x++;
while(y>q[i].r) Del[a[y]],y--;
while(x>q[i].l) x--,insert(a[x]);
while(y<q[i].r) y++,insert(a[y]);
// cout<<x<<" "<<y<<" "<<q[i].k<<"
";
ans[q[i].id]=k_th(q[i].k+1);
}
for(int i=1;i<=m;i++){
cout<<ans[i]<<"
";
}
}