Time Limit: 6000MS | Memory Limit: 65536K | |
Total Submissions: 17095 | Accepted: 5349 |
Description
Input
Output
Sample Input
7 2 1 5 2 6 3 7 4 1 5 3 2 7 1
Sample Output
3 2
Source
Treap模板题
这道题是支持离线的,所以我们可以将区间按左端点从小到大排序,每次相应加点和删点在求出Treap中第k小的数。
Treap模板写挂了...整整调了3个小时才找出错...最后发现是在删点时没有将节点数减1...QAQ
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<cstdlib> #define F(i,j,n) for(int i=(j);i<=(n);i++) #define D(i,j,n) for(int i=(j);i>=(n);i--) #define LL long long #define pa pair<int,int> #define MAXN 100005 using namespace std; int n,m,root=0,tot=0,b[MAXN],ans[MAXN]; struct tree_type { int l,r,s,rnd,v,w; }t[MAXN]; struct query_type { int l,r,x,num; }a[MAXN]; int read() { int ret=0,flag=1; char ch=getchar(); while (ch<'0'||ch>'9') { if (ch=='-') flag=-1; ch=getchar(); } while (ch>='0'&&ch<='9') { ret=ret*10+ch-'0'; ch=getchar(); } return ret*flag; } void rturn(int &k) { int tmp=t[k].l; t[k].l=t[tmp].r; t[tmp].r=k; t[tmp].s=t[k].s; t[k].s=t[t[k].l].s+t[t[k].r].s+t[k].w; k=tmp; } void lturn(int &k) { int tmp=t[k].r; t[k].r=t[tmp].l; t[tmp].l=k; t[tmp].s=t[k].s; t[k].s=t[t[k].l].s+t[t[k].r].s+t[k].w; k=tmp; } void ins(int &k,int x) { if (!k) { k=++tot; t[k].v=x; t[k].s=t[k].w=1; t[k].l=t[k].r=0; t[k].rnd=rand(); return; } t[k].s++; if (t[k].v==x) t[k].w++; else if (t[k].v>x) { ins(t[k].l,x); if (t[t[k].l].rnd<t[k].rnd) rturn(k); } else { ins(t[k].r,x); if (t[t[k].r].rnd<t[k].rnd) lturn(k); } } void del(int &k,int x) { if (t[k].v==x) { if (t[k].w>1) t[k].w--,t[k].s--; else if (!t[k].l||!t[k].r) k=t[k].l+t[k].r; else if (t[t[k].l].rnd<t[t[k].r].rnd) { rturn(k); del(k,x); } else { lturn(k); del(k,x); } return; } t[k].s--; if (x<t[k].v) del(t[k].l,x); else del(t[k].r,x); } int getans(int k,int x) { int ln=t[t[k].l].s; if (ln<x&&ln+t[k].w>=x) return t[k].v; else if (x<=ln) return getans(t[k].l,x); else return getans(t[k].r,x-ln-t[k].w); } bool cmp(query_type x,query_type y) { return x.l==y.l?x.r<y.r:x.l<y.l; } int main() { t[0].s=0; a[0].l=1;a[0].r=0; n=read();m=read(); F(i,1,n) b[i]=read(); F(i,1,m) { a[i].l=read(); a[i].r=read(); a[i].x=read(); a[i].num=i; } sort(a+1,a+m+1,cmp); F(i,1,m) { if (a[i].l>a[i-1].r) { root=0; F(j,a[i].l,a[i].r) ins(root,b[j]); } else { F(j,a[i-1].l,a[i].l-1) del(root,b[j]); F(j,a[i-1].r+1,a[i].r) ins(root,b[j]); } ans[a[i].num]=getans(root,a[i].x); } F(i,1,m) printf("%d\n",ans[i]); }