链接:

https://vjudge.net/problem/POJ-2104#author=malic

题意:

给定一个数组 a[1...n],数组元素各不相同,你的程序要对每次查询Q(i,j,k)作出回答,其中Q(i,j,k)的含义为在数组a[i...j]中第k大的数字.

例如,给出数组a=(1, 5, 2, 6, 3, 7, 4).查询语句为Q(2, 5, 3),即从(5,2,6,3)中找出第3大的元素,将之排序得到(2, 3, 5, 6),故第三大的数字是5,所以这次查询的结果应当为5.

思路:

主席树模板。

代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
using namespace std;
typedef long long LL;
const int MAXN = 1e5+10;
struct Node
{
int v;
int pos;
bool operator < (const Node& that)const
{
return this->v < that.v;
}
}node[MAXN];
int Sca[MAXN], Ori[MAXN]; struct Segment
{
int l, r;
int cnt;
}Seg[MAXN*30];
int Tree_root[MAXN*30];
int cnt = 0, tree_cnt = 0;
int n, m; int Insert(int num, int last, int l, int r)
{
++tree_cnt;//树节点数加1
Seg[tree_cnt].cnt = Seg[last].cnt+1;//数加1
int nownode = tree_cnt;//记录当前节点数用于返回
int mid = (l+r)/2;
if (l == r)
{
return nownode;
}
else if (num <= mid)
{
Seg[nownode].l = Insert(num, Seg[last].l, l, mid);
Seg[nownode].r = Seg[last].r;
}
else
{
Seg[nownode].l = Seg[last].l;
Seg[nownode].r = Insert(num, Seg[last].r, mid+1, r);
}
return nownode;
} int Query(int x, int y, int l, int r, int k)
{
// cout << Seg[x].cnt << ' ' << Seg[y].cnt << ' ' << l << ' ' << r << endl;
if (l == r)
return l;
int sum = (Seg[Seg[y].l].cnt - Seg[Seg[x].l].cnt);
int mid = (l+r)/2;
if (k <= sum)
return Query(Seg[x].l, Seg[y].l, l, mid, k);
else
return Query(Seg[x].r, Seg[y].r, mid+1, r, k-sum);
} void scatter()
{
//离散化
cnt = 0;
int pos = 0;
sort(node+1, node+1+n);
Ori[++pos] = node[1].v;
Sca[node[1].pos] = ++cnt;
for (int i = 2;i <= n;i++)
{
if (node[i].v == node[i-1].v)
{
Sca[node[i].pos] = cnt;
}
else
{
Sca[node[i].pos] = ++cnt;
Ori[++pos] = node[i].v;
}
}
} int main()
{
scanf("%d %d", &n, &m);
for (int i = 1;i <= n;i++)
scanf("%d", &node[i].v), node[i].pos = i;
scatter();
Tree_root[0] = 0;
Seg[0].cnt = 0;
for (int i = 1;i <= n;i++)
{
int pos = Insert(Sca[i], Tree_root[i-1], 1, n);
Tree_root[i] = pos;
}
while (m--)
{
int x, y, k;
scanf("%d %d %d", &x, &y, &k);
int pos = Query(Tree_root[x-1], Tree_root[y], 1, n, k);
printf("%d\n", Ori[pos]);
} return 0;
}
/*
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
*/

最新文章

  1. 决策树ID3算法的java实现(基本试用所有的ID3)
  2. jQuery 使得文本框获得焦点
  3. 如何用ABBYY FineReader识别图片中的文本
  4. 未来的 Web:九个不可思议的 WebGL 应用试验
  5. &amp;1的用法
  6. Hashtable、Dictionary和List 谁效率更高
  7. RabbitMQ基础总结
  8. 最全的ORACLE-SQL笔记
  9. 12C CLONE PDB and config service_listener
  10. vps安装wordpress遇到的问题(lnmp)
  11. maven依赖jar包更新,业务jar需同步更新(业务jar依赖API)
  12. cocos2d导入iOS原生项目
  13. SpringBoot的注解:@SpringBootApplication注解 vs @EnableAutoConfiguration+@ComponentScan+@Configuration
  14. SpringMVC提供两种校验机制
  15. Linux kernel的中断子系统之(四):High level irq event handler
  16. JAVA进阶16
  17. ssh登录
  18. AFNetworking网络请求数据
  19. exchange 2010 的两个错误
  20. Android自定义实现微信标题栏

热门文章

  1. python实现矩阵乘法的方法
  2. 如何实现在Eclipse导入MySQL驱动包
  3. 【SSM】---增删改查
  4. 【神经网络与深度学习】【Qt开发】【VS开发】从caffe-windows-visual studio2013到Qt5.7使用caffemodel进行分类的移植过程
  5. Android尺寸适配问题
  6. java_时间戳与Date_相互转化的实现代码
  7. Git-版本控制 (三)
  8. Jquery复习(四)之text()、html()、val()
  9. [转载]Linux运行模式及紧急、救援模式
  10. 使用QtXlsx来读写excel文件