主席樹模板(查詢區間第K大的元素)
阿新 • • 發佈:2020-08-07
/**************************** * Author : W.A.R * * Date : 2020-08-07-17:13 * ****************************/ /* 主席樹多組樣例一定要記得初始化sz=0!!!!!!!!!! */ #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<map> #include<stack> #include<string> using namespace std; typedef long long ll; const int maxn=1e5+50; const ll mod=1e9+7; namespace Fast_IO{ //orz laofu const int MAXL((1 << 18) + 1);int iof, iotp; char ioif[MAXL], *ioiS, *ioiT, ioof[MAXL],*iooS=ioof,*iooT=ioof+MAXL-1,ioc,iost[55]; char Getchar(){ if (ioiS == ioiT){ ioiS=ioif;ioiT=ioiS+fread(ioif,1,MAXL,stdin);return (ioiS == ioiT ? EOF : *ioiS++); }else return (*ioiS++); } void Write(){fwrite(ioof,1,iooS-ioof,stdout);iooS=ioof;} void Putchar(char x){*iooS++ = x;if (iooS == iooT)Write();} inline int read(){ int x=0;for(iof=1,ioc=Getchar();(ioc<'0'||ioc>'9')&&ioc!=EOF;)iof=ioc=='-'?-1:1,ioc=Getchar(); if(ioc==EOF)exit(0); for(x=0;ioc<='9'&&ioc>='0';ioc=Getchar())x=(x<<3)+(x<<1)+(ioc^48);return x*iof; } inline long long read_ll(){ long long x=0;for(iof=1,ioc=Getchar();(ioc<'0'||ioc>'9')&&ioc!=EOF;)iof=ioc=='-'?-1:1,ioc=Getchar(); if(ioc==EOF)exit(0); for(x=0;ioc<='9'&&ioc>='0';ioc=Getchar())x=(x<<3)+(x<<1)+(ioc^48);return x*iof; } template <class Int>void Print(Int x, char ch = '\0'){ if(!x)Putchar('0');if(x<0)Putchar('-'),x=-x;while(x)iost[++iotp]=x%10+'0',x/=10; while(iotp)Putchar(iost[iotp--]);if (ch)Putchar(ch); } void Getstr(char *s, int &l){ for(ioc=Getchar();ioc==' '||ioc=='\n'||ioc=='\t';)ioc=Getchar(); if(ioc==EOF)exit(0); for(l=0;!(ioc==' '||ioc=='\n'||ioc=='\t'||ioc==EOF);ioc=Getchar())s[l++]=ioc;s[l] = 0; } void Putstr(const char *s){for(int i=0,n=strlen(s);i<n;++i)Putchar(s[i]);} } // namespace Fast_IO using namespace Fast_IO; struct node { int l,r,v; }tree[maxn*20]; int rt[maxn],sz=0; int a[maxn],b[maxn]; void build(int &rt,int l,int r){ rt=++sz;tree[rt].v=0; if(l==r)return; int mid=(l+r)>>1; build(tree[rt].l,l,mid);build(tree[rt].r,mid+1,r); } int update(int o,int l,int r,int pos){ int oo=++sz;tree[oo]=tree[o];tree[oo].v++; if(l==r)return oo; int mid=(l+r)>>1; if(mid>=pos)tree[oo].l=update(tree[oo].l,l,mid,pos);else tree[oo].r=update(tree[oo].r,mid+1,r,pos); return oo; } int query(int x,int y,int l,int r,int pos){ if(l==r)return l; int mid=(l+r)>>1;int sum=tree[tree[y].l].v-tree[tree[x].l].v; if(sum>=pos)return query(tree[x].l,tree[y].l,l,mid,pos);else return query(tree[x].r,tree[y].r,mid+1,r,pos-sum); } int main(){ int T; scanf("%d",&T); while(T--){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); b[i]=a[i]; } sort(b+1,b+1+n);int q=unique(b+1,b+1+n)-b-1; sz=0;build(rt[0],1,q); for(int i=1;i<=n;i++){ int p=lower_bound(b+1,b+1+q,a[i])-b; rt[i]=update(rt[i-1],1,q,p); } while(m--){ int l,r,x;scanf("%d%d%d",&l,&r,&x); printf("%d\n",b[query(rt[l-1],rt[r],1,q,x)]); } } }