Topic links: http://poj.org/problem?id=2104
Title effect: as well as a sequence number of a given n, m operations, each operation comprising l, r, k, find the interval [l, r] k-th largest
Problem-solving ideas: the maximum segment tree can only maintain the minimum sequence, consider the establishment of a segment tree for each input sequence prefix, that contains n pieces of tree line, this will certainly burst memory. Two adjacent segments of the same tree, in fact, there are many different probably log n nodes, we opened a new log n nodes on it. Each sum is stored node number of the current node number appears, for the interval [L, r], r pieces we use the first segment tree subtracting l-1 pieces of segment tree is obtained [L, r] interval the number of times each node appears, starting with its left sub-tree began to look for to determine whether the left sub-tree node number is greater than the sum equal to k, if k greater than or equal to find a large tree on the left sub k, or find the first right subtree k-sum large.
Code:
#include<iostream> #include<algorithm> #include<vector> #include<cstdio> using namespace std; const int maxn=1e5+6; int n,m,cnt,root[maxn],a[maxn],x,y,k; struct node{ int l,r,sum; }T[maxn*40]; vector<int> v; int getid(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } void update(int l,int r,int &x,int y,int pos){ T[++cnt]=T[y],T[cnt].sum++ ,x=cnt; if(l==r) return; int mid=l+r>>1; if(mid>=pos) update(l,mid,T[x].l,T[y].l,pos); else update(mid+1,r,T[x].r,T[y].r,pos); } int query(int l,int r,int x,int y,int k){ if(l==r) return l; int mid=l+r>>1; int sum=T[T[y].l].sum-T[T[x].l].sum; if(sum>=k) return query(l,mid,T[x].l,T[y].l,k); else return query(mid+1,r,T[x].r,T[y].r,k-sum); } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]),v.push_back(a[i]); sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end()); for(int i=1;i<=n;i++) update(1,n,root[i],root[i-1],getid(a[i])); for(int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&k); printf("%d\n",v[query(1,n,root[x-1],root[y],k)-1]); } return 0; }