HDU 2665 && POJ 2104(主席树)
http://poj.org/problem?id=2104
对权值进行建树(这个时候树的叶子是数组b的有序数列),然后二分查找原数列中每个数在有序数列中的位置(即第几小),对每一个前缀[1,i]建一棵树。用到前缀和的思想,区间第k小就可以直接查找T[r] - T[l-1]区间内第k小的数。如果对每一个前缀建一棵树,无疑会MLE,这个时候用到主席树。
主席树在我的理解:在更新的时候,只有一棵树中的一条路径有改变,这个时候我们只要修改改变的那条路径,而不是重新建一棵树。要做的是直接把上一个版本的线段树给现在的版本,然后对现在版本进行更新。
睡觉前不要打代码..做了一个晚上主席树的梦.
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <iostream>
#include <stack>
using namespace std;
#define N 100010 /*
主席树
http://www.bilibili.com/video/av4619406/
http://www.cnblogs.com/Empress/p/4652449.html
题意:在一堆数里面有m个询问,每个询问求区间[l,r]里面的第k小的数是哪个.
要认识权值线段树:在以节点i为根的树中,[1,i]区间内包含的数的个数.
*/
struct node
{
int l, r, sum;//sum储存的就是权值
}tree[N*];
int root[N];//储存根节点
int a[N], b[N], tot; void update(int pre, int &now, int x, int l, int r)
{
tree[++tot] = tree[pre];//把上一个版本的线段树给现在的版本,然后对要修改的那条链进行更新
now = tot;
tree[now].sum++;//因为插入了新的数,所以要更新+1
if(l == r) return ;
int m = (l + r) >> ;
if(x <= m) update(tree[pre].l, tree[now].l, x, l, m);
else update(tree[pre].r, tree[now].r, x, m + , r);
} int query(int left, int right, int k, int l, int r)
{
if(l == r) return l;
int m = (l + r) >> ;
int sum = tree[tree[right].l].sum - tree[tree[left].l].sum;//如果左子树已经有k个数,那么答案就在左边
if(k <= sum) return query(tree[left].l, tree[right].l, k, l, m);
else return query(tree[left].r, tree[right].r, k - sum, m + , r);
} int main()
{
// int t;
// scanf("%d", &t);
// while(t--) {
int n, m;
scanf("%d%d", &n, &m);
tot = ;
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + , b + + n);
int cnt = unique(b + , b + + n) - b - ;
for(int i = ; i <= n; i++) {
a[i] = lower_bound(b + , b + + cnt, a[i]) - b; //二分找到a[i]的位置
// printf("QQQQQ\n");
update(root[i-], root[i], a[i], , cnt); //root[i-1]表示上一个版本的线段树
}
for(int i = ; i <= m; i++) {
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
int ans = query(root[l-], root[r], k, , cnt); //ans是第k个数的位置
printf("%d\n", b[ans]); //因为询问的是哪个数,所以要b[ans]
}
// }
return ;
}
HDU 2665 && POJ 2104(主席树)的更多相关文章
- K-th Number Poj - 2104 主席树
K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...
- [poj 2104]主席树+静态区间第k大
题目链接:http://poj.org/problem?id=2104 主席树入门题目,主席树其实就是可持久化权值线段树,rt[i]维护了前i个数中第i大(小)的数出现次数的信息,通过查询两棵树的差即 ...
- hdu 2665 Kth number 主席树
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Prob ...
- poj 2104 主席树(区间第k大)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 44940 Accepted: 14946 Ca ...
- HDU - 2665 Kth number 主席树/可持久化权值线段树
题意 给一个数列,一些询问,问$[l,r]$中第$K$大的元素是哪一个 题解: 写法很多,主席树是最常用的一种之一 除此之外有:划分树,莫队分块,平衡树等 主席树的定义其实挺模糊, 一般认为就是可持久 ...
- POJ 2104 - 主席树 / 询问莫队+权值分块
传送门 题目大意应该都清楚. 今天看到一篇博客用分块+莫对做了这道题,直接惊呆了. 首先常规地离散化后将询问分块,对于某一询问,将莫队指针移动到指定区间,移动的同时处理权值分块的数字出现次数(单独.整 ...
- hdu 4417,poj 2104 划分树(模版)归并树(模版)
这次是彻底把划分树搞明确了,与此同一时候发现了模版的重要性.敲代码一个字符都不能错啊~~~ 划分树具体解释:点击打开链接 题意:求一组数列中随意区间不大于h的个数. 这个题的做法是用二分查询 求给定 ...
- POJ 2104 主席树模板题
#include <iostream> #include <cstdio> #include <algorithm> int const maxn = 200010 ...
- hdu 2665 Kth number(划分树模板)
http://acm.hdu.edu.cn/showproblem.php?pid=2665 [ poj 2104 2761 ] 改变一下输入就可以过 http://poj.org/problem? ...
随机推荐
- AWE、加载计数器错误
错误#1 16:28 2012-7-25数据库服务器A想开启下sql server 2000的AWE.结果发现在查询分析器中执行RECONFIGURE时报错.运行的语句为: sp_configure ...
- django 用户登陆注册
注册登陆 views.py #!/usr/bin/env python # -*- coding:utf- -*- from django.shortcuts import render,render ...
- 记32位程序(使用3gb用户虚拟内存)使用D3DX9导致的一个崩溃的问题
为了增加32位程序的用户虚拟内存的使用量,我们使用了/LARGEADDRESSAWARE编译选项来使32位程序可能使用到3gb的内存,能否使用到3gb内存也跟平台.系统和设置有关系,现摘抄部分作为参考 ...
- LinkedHashMap 和 LRU算法实现
个人觉得LinkedHashMap 存在的意义就是为了实现 LRU 算法. public class LinkedHashMap<K,V> extends HashMap<K,V&g ...
- 理解JDBC和JNDI
下面的英文是我找过来的,因为是英文所以不敢翻译出来误导别人,但是它描述的确实恰到好处,比所谓网上的JNDI和JDBC云云的解释要精辟很多,如果遇到不认识的单词,用有道吧~~:) The Java Na ...
- Swift游戏实战-跑酷熊猫 10 视差滚动背景
原理 实现 勘误 “实现”的视频中有个错误,如下 背景移动时有个错误,看红色部分,近景归位时,第二张图片的下标是1 if arrBG[0].position.x + arrBG[0].frame.wi ...
- 转:NodeJS、NPM安装配置步骤
1.windows下的NodeJS安装是比较方便的(v0.6.0版本之后,支持windows native),只需要登陆官网(http://nodejs.org/),便可以看到下载页面. 2.下载完 ...
- Linux 系统结构
Linux的系统结构一般由四部分组成 内核 1)内核 操作系统的核心,具有最基本的功能:内存管理.进程管理.设备驱动管理.文件系统管理,网络管理 内核版本(kernel)查看的三种方法 cat /pr ...
- Python学习总结6:字符串格式化操作及方法总结
1. 格式化操作(%) Python中内置有对字符串进行格式化的操作. 模板 格式化字符串时,Python使用一个字符串作为模板.模板中有格式符,这些格式符为真实值预留位置,并说明真实数值应该呈现的格 ...
- android EditText长按屏蔽ActionMode context菜单但保留选择工具功能
最近项目要求屏蔽EditText 长按出来的ActionMode菜单,但是要保留选择文本功能.这个屏蔽百度会出现各种方法,这里说一下我的思路: 1.屏蔽百度可知setCustomSelectionAc ...