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(主席树)的更多相关文章

  1. K-th Number Poj - 2104 主席树

    K-th Number Poj - 2104 主席树 题意 给你n数字,然后有m次询问,询问一段区间内的第k小的数. 解题思路 这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简 ...

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

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

  3. hdu 2665 Kth number 主席树

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

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

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

  5. HDU - 2665 Kth number 主席树/可持久化权值线段树

    题意 给一个数列,一些询问,问$[l,r]$中第$K$大的元素是哪一个 题解: 写法很多,主席树是最常用的一种之一 除此之外有:划分树,莫队分块,平衡树等 主席树的定义其实挺模糊, 一般认为就是可持久 ...

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

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

  7. hdu 4417,poj 2104 划分树(模版)归并树(模版)

    这次是彻底把划分树搞明确了,与此同一时候发现了模版的重要性.敲代码一个字符都不能错啊~~~ 划分树具体解释:点击打开链接 题意:求一组数列中随意区间不大于h的个数. 这个题的做法是用二分查询  求给定 ...

  8. POJ 2104 主席树模板题

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

  9. hdu 2665 Kth number(划分树模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=2665 [ poj 2104 2761 ]  改变一下输入就可以过 http://poj.org/problem? ...

随机推荐

  1. iOS NSUserDefaults的基本使用

    /** * NSUserDefaults可以进行轻量级的数据存储 * NSUserDefaults支持的数据类型: NSString, NSNumber, NSDate, NSArray, * NSD ...

  2. IIS URL Rewrite redirect from one Domain to another

    IIS URL Rewrite enables Web administrators to create powerful rules to implement URLs that are easie ...

  3. mysql在线改表结构 pt-online-schema-change

    https://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html 不锁表更改数据库表结构 pt-online-s ...

  4. 使用dbms_system追踪其它session

    dbms_system是内部包,建议在官方指导下使用该包. SQL> desc dbms_system PROCEDURE ADD_PARAMETER_VALUE Argument Name T ...

  5. Reporting services导出的Excel文件避免出现隐藏行列的布局

    开发Reporting services时,为了避免在导出的Excel文件中出现隐藏的行和列,必须遵循以下规则: 1.Page header中的Textbox直接必须紧密贴合在一起 2.Page he ...

  6. Java基础之创建窗口——使用卡片布局管理器(TryCardLayout)

    控制台程序. 卡片布局管理器会生成一叠组件——一个组件放在另一个组件的上面.添加到容器中的第一个组件在堆栈的顶部,因此是可见的,添加的最后一个组件在堆栈的底部.使用默认的构造函数CardLayout( ...

  7. java 笔记(2) —— 内部类的作用

    一.内部类简介 个人觉得内部类没多少研究价值,GUI中的事件响应算是非常典型的应用了. Java内部类其实在J2EE编程中使用较少,不过在窗口应用编程中特别常见,主要用来事件的处理.其实,做非GUI编 ...

  8. iOS 提交代码出现提示弹出框显示 “A commit message is required to perform this operation.Enter a commit message and try again.“

    需要你写一下你确认提交的信息,就是你这次提交上去修改了什么功能,简单描述一下

  9. C++之路进阶——codevs2313(星际竞速)

    2313 星际竞速 2010年省队选拔赛山东  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master     题目描述 Description 10 年一度的银河系 ...

  10. DataFrame使用mysql数据

    错误提示:  Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc ...