洛谷P1533 可怜的狗狗 [平衡树,FHQ_Treap]
可怜的狗狗
题目背景
小卡由于公务需要出差,将新家中的狗狗们托付给朋友嘉嘉,但是嘉嘉是一个很懒的人,他才没那么多时间帮小卡喂狗狗。
题目描述
小卡家有N只狗,由于品种、年龄不同,每一只狗都有一个不同的漂亮值。漂亮值与漂亮的程度成反比(漂亮值越低越漂亮),吃饭时,狗狗们会按顺序站成一排等着主人给食物。
可是嘉嘉真的很懒,他才不肯喂这么多狗呢,这多浪费时间啊,于是他每次就只给第i只到第j只狗中第k漂亮的狗狗喂食(好狠心的人啊)。而且为了保证某一只狗狗不会被喂太多次,他喂的每个区间(i,j)不互相包含。
输入输出格式
输入格式:
第一行输入两个数n,m,你可以假设n<300001 并且 m<50001;m表示他喂了m次。
第二行n个整数,表示第i只狗的漂亮值为ai。
接下来m行,每行3个整数i,j,k表示这次喂食喂第i到第j只狗中第k漂亮的狗的漂亮值。
输出格式:
M行,每行一个整数,表示每一次喂的那只狗漂亮值为多少。
输入输出样例
输出样例#1:
3
2
分析:
$Noip$前复习一波$FHQ\_Treap$。
很模板了,求$k$小值,把询问区间排个序再依次处理就行了。
Code:
//It is made by HolseLee on 7th Nov 2018 //Luogu.org P1533 #include<bits/stdc++.h> using namespace std; const int N=3e5+7; int n,m,tot,root,a[N],ch[N][2],val[N],siz[N],p[N],ans[N]; struct Ques { int l,r,k,id; inline bool operator < (const Ques x) const { return l==x.l ? r<x.r : l<x.l; } }q[N]; inline int read() { char ch=getchar(); int x=0; bool flag=false; while( ch<'0' || ch>'9' ) { if( ch=='-' ) flag=true; ch=getchar(); } while( ch>='0' && ch<='9' ) { x=x*10+ch-'0'; ch=getchar(); } return flag ? -x : x; } inline void pushup(int rt) { siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1; } void split(int rt,int k,int &x,int &y) { if( !rt ) x=y=0; else { if( val[rt]<=k ) x=rt, split(ch[rt][1],k,ch[rt][1],y); else y=rt, split(ch[rt][0],k,x,ch[rt][0]); pushup(rt); } } int merge(int x,int y) { if( !x || !y ) return x+y; if( p[x]<p[y] ) { ch[x][1]=merge(ch[x][1],y); pushup(x); return x; } else { ch[y][0]=merge(x,ch[y][0]); pushup(y); return y; } } inline int neo(int v) { siz[++tot]=1; val[tot]=v; p[tot]=rand(); return tot; } inline void insert(int v) { int x,y; split(root,v,x,y); root=merge(merge(x,neo(v)),y); } inline void delet(int v) { int x,y,z; split(root,v,x,y); split(x,v-1,x,z); z=merge(ch[z][0],ch[z][1]); root=merge(merge(x,z),y); } int Rank(int u,int k) { if( siz[ch[u][0]]==k-1 ) return val[u]; else if( siz[ch[u][0]]>=k ) return Rank(ch[u][0],k); return Rank(ch[u][1],k-siz[ch[u][0]]-1); } int main() { srand(time(0)); n=read(); m=read(); for(int i=1; i<=n; ++i) a[i]=read(); for(int i=1; i<=m; ++i) { q[i].l=read(), q[i].r=read(), q[i].k=read(); q[i].id=i; } sort(q+1,q+m+1); int L=1, R=0; for(int i=1; i<=m; ++i) { while( R<q[i].r ) insert(a[++R]); while( L<q[i].l ) delet(a[L++]); ans[q[i].id]=Rank(root,q[i].k); } for(int i=1; i<=m; ++i) printf("%d\n",ans[i]); return 0; }
蒟蒻写博客不易,如果有误还请大佬们提出
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com
如需转载,请署名作者并附上原文链接,蒟蒻非常感激
名称:HolseLee
博客地址:www.cnblogs.com/cytus
个人邮箱:1073133650@qq.com