K-th Number Poj - 2104 主席树

题意

给你n数字,然后有m次询问,询问一段区间内的第k小的数。

解题思路

这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简单,但是真的不会。限时结束后,学长说这个题是简单的主席树的入门题,我没学过啊。

如果你也没有学过的话,建议看我的另一篇博客,上面有自己的总结和一些博客推荐,就不用自己一个一个找了,点我进去

哦, 这个题是主席树的模板题。

代码实现

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1e5+7;
int root[maxn], a[maxn], x, y, k;
int n, m, cnt, tot;
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; //这里用vector进行的离散化,比较简单
}
void update(int l, int r, int &x, int y, int pos) //注意参数中的l和r是区间范围,和node里面的l和r不一样,node里面的l和r表示左右子树的编号
//这里相当于建树+更新了,有的博客还单独写了一个build函数,然后再进行update,都行。
{
t[++cnt]=t[y];
t[cnt].sum++;
x=cnt;//这里是把新节点的编号记录下来
if(l==r) return ;
int mid=(l+r)>>1;
if(pos<=mid)//如果需要添加的编号小于mid,就向左子树走
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) //这里的l和r也是区间范围,x是前一个线段树
{
if(l==r)
return l;
int mid=(l+r)>>1;
int sum=t[t[y].l].sum - t[t[x].l].sum;
if(k<=sum)
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() );//去重
tot=v.size(); //注意这里很重要,1到tot是我们主席树端点的个数。
for(int i=1; i<=n; i++)
{
update(1, tot, 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, tot, root[x-1], root[y], k) - 1]);
}
return 0;
}

K-th Number Poj - 2104 主席树的更多相关文章

  1. [poj 2104]主席树+静态区间第k大

    题目链接:http://poj.org/problem?id=2104 主席树入门题目,主席树其实就是可持久化权值线段树,rt[i]维护了前i个数中第i大(小)的数出现次数的信息,通过查询两棵树的差即 ...

  2. poj 2104 主席树(区间第k大)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 44940   Accepted: 14946 Ca ...

  3. K-th Number POJ - 2104 划分树

    K-th Number You are working for Macrohard company in data structures department. After failing your ...

  4. POJ 2104 - 主席树 / 询问莫队+权值分块

    传送门 题目大意应该都清楚. 今天看到一篇博客用分块+莫对做了这道题,直接惊呆了. 首先常规地离散化后将询问分块,对于某一询问,将莫队指针移动到指定区间,移动的同时处理权值分块的数字出现次数(单独.整 ...

  5. POJ 2104 主席树模板题

    #include <iostream> #include <cstdio> #include <algorithm> int const maxn = 200010 ...

  6. 主席树 【权值线段树】 && 例题K-th Number POJ - 2104

    一.主席树与权值线段树区别 主席树是由许多权值线段树构成,单独的权值线段树只能解决寻找整个区间第k大/小值问题(什么叫整个区间,比如你对区间[1,8]建立一颗对应权值线段树,那么你不能询问区间[2,5 ...

  7. K-th Number POJ - 2104

    K-th Number POJ - 2104 You are working for Macrohard company in data structures department. After fa ...

  8. BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数

    BZOJ_4026_dC Loves Number Theory _主席树+欧拉函数 Description  dC 在秒了BZOJ 上所有的数论题后,感觉萌萌哒,想出了这么一道水题,来拯救日益枯 竭 ...

  9. HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. mongdb 学习

    一:安装1.首先到官网(http://www.mongodb.org/downloads )下载合适的安装包2.安装mongodb3. cmd 命令切换到安装目录bin 下面 mongod --dbp ...

  2. toString和toLocalString

    toLocalString()是调用每个数组元素的 toLocaleString() 方法,然后使用地区特定的分隔符把生成的字符串连接起来,形成一个字符串. toString()方法获取的是Strin ...

  3. 下载csv

    export function downloadCsv(val, key, name, keyName) { if (val.length) { let str = [] str.push(keyNa ...

  4. 命令——tree

    tree——以树形结构显示目录文件 [root@centos71 ~]# yum provides tree Loaded plugins: fastestmirror Loading mirror ...

  5. font-size:0; 消除空白间隙

    使用font-size:0解决设置inline-block引起的空白间隙问题 一.空白间隙问题 在进行页面布局的时候为了页面代码所谓整洁刻度,往往会设置缩进或是换行,但是元素display为inlin ...

  6. AC自动机及其模板

    模板 #include<queue> #include<stdio.h> #include<string.h> using namespace std; ; ; ; ...

  7. Oulipo【Hash】

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45515   Accepted: 18181 Descript ...

  8. Oralce动态的创建按月的分区

    说明: XXX为一个配置表,里面配置了要分区的表明,即CODENO = 'PARTITIONTABLENAME',只有每个月月底的时候,才会进入IF的判断,此外还有一个定时任务,每天去执行即可. 存储 ...

  9. leetcode 62. 不同路径(C++)

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为“Finish”). 问总共有多 ...

  10. (转)websphere内存溢出,手动导出was的phd和javacore文件

    原文:https://www.cnblogs.com/zhengbn/p/3499700.html 1:服务器-->服务器类型-->WebSphere Application Server ...