動態開點主席樹板子
阿新 • • 發佈:2020-08-03
#include<bits/stdc++.h> #define getsize(p) (p?p->sz:0) using namespace std; typedef long long ll; const int N=2e5+10; struct node{ int l,r; int sz; node *ls,*rs; }pool[N*40]; node *rt[N]; int idx; vector<int> num; int a[N]; node * copynode(node *rt){ node *p=pool+(++idx); pool[idx]View Code=*rt; return p; } node * newnode(int l,int r){ node *p=pool+(++idx); p->l=l,p->r=r; return p; } node *insert(node *rt,int l,int r,int x){ node *p; if(rt) p=copynode(rt); else p=newnode(l,r); p->sz++; int mid=l+r>>1; if(p->l==x&&p->r==x){return p; } if(x<=mid) p->ls=insert(p->ls,l,mid,x); else p->rs=insert(p->rs,mid+1,r,x); return p; } int query(node *pl,node *pr,int k){ if(pr->l==pr->r) return pr->l; int n; if(!pl){ n=getsize(pr->ls); if(n>=k) return query(0,pr->ls,k); else return query(0,pr->rs,k-n); } else{ n=getsize(pr->ls)-getsize(pl->ls); if(n>=k) return query(pl->ls,pr->ls,k); else return query(pl->rs,pr->rs,k-n); } } int main(){ ios::sync_with_stdio(false); int n,m; cin>>n>>m; int i; for(i=1;i<=n;i++){ cin>>a[i]; num.push_back(a[i]); } sort(num.begin(),num.end()); num.erase(unique(num.begin(),num.end()),num.end()); for(i=1;i<=n;i++){ int x=lower_bound(num.begin(),num.end(),a[i])-num.begin()+1; rt[i]=insert(rt[i-1],1,n,x); } int l,r,k; while(m--){ cin>>l>>r>>k; cout<<num[query(rt[l-1],rt[r],k)-1]<<endl; } }