POJ 2104 K-th Number

来源:互联网 发布:礼券提货系统源码 php 编辑:程序博客网 时间:2024/05/14 05:23

题意:给定一个数组,输入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;}

2、

用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)]);        }}}


0 0
原创粉丝点击