题意:给定一个数组,输入i, j, k,也就是询问i到j之间第k大的数
思路:暴力,主席树(模板题);
1、
暴力就是对每一个数标好顺序,然后排序(这时候预处理完成);
对于每个查询,暴力的扫一遍,遇到序号在i,j之间的数就k--,k=0是,就是所找的数
/*暴力法 Time: 7563MS */ #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int N = 100005; struct node{ int val,id; }nod[N]; bool cmp(node a, node b){ return a.val < b.val; } int main(){ int n, m, l, r, k; while(~scanf("%d%d",&n,&m)){ for(int i = 1; i <= n; i++){ scanf("%d", &nod[i].val); nod[i].id = i; } sort(nod+1, nod+n+1, cmp); for(int i = 0; i < m; i++){ scanf("%d%d%d", &l, &r, &k); for(int j = 1; j <= n; j++){ if(nod[j].id >= l && nod[j].id <= r) k--; if(k == 0){ printf("%d\n", nod[j].val); break; } } } } return 0; }
用a[N]存储原来的数字,a2[size]存储排好序的数字;
主席树,T[i]都维护着size大小的线段树,而该线段树维护的信息为:在a[i] 到a[n]数字集合中,size种数字分别出现的次数。
我是看着这个理解的
http://blog.csdn.net/sprintfwater/article/details/9162041
1422MS
#include <cstdio> #include <iostream> #include <cstring> #include <string.h> #include <algorithm> using namespace std; const int N = 100005; const int M = N * 30; int n,q,m,tot; int a[N],t[N]; int T[M],lson[M],rson[M],c[M]; void Init_hash(){ for(int i = 1; i <= n ;i++) t[i] = a[i]; sort(t+1, t+n+1); m=unique(t+1,t+1+n)-t-1; } int build(int l, int r) { int root = tot++; c[root] = 0; if(l != r){ int mid = (l+r)>>1; lson[root] = build(l, mid); rson[root] = build(mid+1, r); } return root; } int hash(int x){ return lower_bound(t+1, t+1+m, x)-t; } int update(int root, int pos, int val){ int newroot = tot++, tmp = newroot; c[newroot] = c[root] + val; int l = 1, r = m; while(l < r){ int mid = (l+r)>>1; if(pos <= mid){ lson[newroot] = tot++; rson[newroot] = rson[root]; newroot = lson[newroot]; root = lson[root]; r = mid; } else { rson[newroot] = tot++; lson[newroot] = lson[root]; newroot = rson[newroot]; root = rson[root]; l = mid+1; } c[newroot] = c[root] + val; } return tmp; } int query(int lr, int rr, int k){ int l = 1, r = m; while( l < r){ int mid = (l+r)>>1; if(c[lson[lr]] - c[lson[rr]] >= k){ r = mid; lr = lson[lr]; rr = lson[rr]; } else { l = mid + 1; k -= c[lson[lr]] - c[lson[rr]]; lr = rson[lr]; rr = rson[rr]; } } return l; } int main(){ while(~scanf("%d%d",&n,&q)){ tot=0; for(int i = 1; i <= n; i++) scanf("%d",a+i); Init_hash(); T[n+1] = build(1, m); for(int i = n; i ; i--){ int pos = hash(a[i]); T[i] = update(T[i+1],pos,1); } while(q--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%d\n",t[query(T[l],T[r+1],k)]); } } }