POJ2104、POJ2761:

题意:区间第K小。

两道题几乎是一样的。

AC代码:

/*---------------------------------
File name: poj2104.cpp
Author: Snpilola
Creation date: 2019-08-09 14:17
---------------------------------*/
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define mkp make_pair
#define PLL pair<LL, LL>
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;int ls[maxn << 5], rs[maxn << 5], cnt[maxn << 5], root[maxn << 5], tot;
int num[maxn], hash[maxn];void build(int l, int r, int &rt){rt = tot++;cnt[rt] = 0;if(l == r) return;int mid = (l + r) >> 1;build(l, mid, ls[rt]);build(mid + 1, r, rs[rt]);
}void update(int last, int p, int l, int r, int &rt){rt = tot++;ls[rt] = ls[last], rs[rt] = rs[last];cnt[rt] = cnt[last] + 1;    if(l == r) return;int mid = (l + r) >> 1;if(p <= mid) update(ls[last], p, l, mid, ls[rt]);else update(rs[last], p, mid + 1, r, rs[rt]);
}int query(int ss, int tt, int l, int r, int k){if(l == r) return l;int mid = (l + r) >> 1, sum = cnt[ls[tt]] - cnt[ls[ss]];if(k <= sum) return query(ls[ss], ls[tt], l, mid, k);else return query(rs[ss], rs[tt], mid + 1, r, k - sum);
}int main(){int n, m, l, r, k;while(~ scanf("%d %d", &n, &m)){for(int i = 1; i <= n; ++i){scanf(" %d", &num[i]);hash[i] = num[i];}sort(hash + 1, hash + 1 + n);int size = unique(hash + 1, hash + 1 + n) - hash - 1;//unique前先sort//unique函数返回最后一个不重复元素,实际数组长度无变化for(int i = 1; i <= n; ++i){num[i] = lower_bound(hash + 1, hash + size + 1, num[i]) - hash;}tot = 0;build(1, size, root[0]);//建空树for(int i = 0; i < 4 * size; i++) printf("%d %d %d\n", root[i], ls[i], rs[i]);//printf("----------\n");for(int i = 1; i <= n; ++i){update(root[i - 1], num[i], 1, size, root[i]);//填树//printf("%d %d %d\n", root[i], ls[root[i]], rs[root[i]]);}while(m--){scanf("%d %d %d", &l, &r, &k);//区间[l, r]的第k小||大printf("%d\n", hash[query(root[l - 1], root[r], 1, size, k)]);}}return 0;
}
/*---------------------------------
File name: poj2761.cpp
Author: Snpilola
Creation date: 2019-08-08 10:32
---------------------------------*/
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define mkp make_pair
#define PLL pair<LL, LL>
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;int a[maxn];
int Hash[maxn];
int root[maxn << 5], ls[maxn << 5], rs[maxn << 5], cnt[maxn << 5];
int tot;void build(int l, int r, int &rt){rt = tot++;cnt[rt] = 0;if(l == r) return;int mid = (l + r) >> 1;build(l, mid, ls[rt]);build(mid + 1, r, rs[rt]);
}void update(int last, int p, int l, int r, int &rt){rt = tot++;ls[rt] = ls[last];rs[rt] = rs[last];cnt[rt] = cnt[last] + 1;if(l == r) return ;int mid = (l + r) >> 1;if(p <= mid) update(ls[rt], p, l, mid, ls[rt]);else update(rs[rt], p, mid + 1, r, rs[rt]);
}int query(int ss, int tt, int l, int r, int k){if(l == r) return r;int mid = (l + r) >> 1;int sum = cnt[ls[tt]] - cnt[ls[ss]];if(k <= sum) query(ls[ss], ls[tt], l, mid, k);else query(rs[ss], rs[tt], mid + 1, r, k - sum);
}int main(){int t; scanf("%d", &t);while(t--){int n, m; scanf("%d %d", &n, &m);for(int i = 1; i <= n; ++i){scanf(" %d", &a[i]);Hash[i] = a[i];}sort(Hash + 1, Hash + 1 + n);int Size = unique(Hash + 1, Hash + 1 + n) - Hash - 1;for(int i = 1; i <= n; i++){a[i] = lower_bound(Hash + 1, Hash + 1 + Size, a[i]) - Hash;}tot = 0;build(1, Size, root[0]);for(int i = 1; i <= n; i++){update(root[i - 1], a[i], 1, Size, root[i]);}while(m--){int i, j, k;scanf("%d %d %d", &i, &j, &k);printf("%d\n", Hash[query(root[i - 1], root[j], 1, Size, k)]);}}return 0;
}

HDU4417:

Input:

1
10 10
0 5 2 7 5 4 3 8 7 7
2 8 6
3 5 0
1 3 1
1 9 4
0 1 0
3 5 5
5 5 1
4 6 3
1 5 7
5 7 3

Output:

Case 1:
4
0
0
3
1
2
0
1
5
1

题意:求给定区间【L, R】中不大于H的数的个数。

思路:只需要改一下query的部分就可以了。

AC代码:

/*---------------------------------
File name: hdu4417.cpp
Author: Snpilola
Creation date: 2019-08-08 11:07
---------------------------------*/
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define LL long long
#define mkp make_pair
#define PLL pair<LL, LL>
#define PII pair<int, int>
#define Pque priority_queue
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;int a[maxn];
int Hash[maxn];
int root[maxn << 5], ls[maxn << 5], rs[maxn << 5], cnt[maxn << 5];
int tot;void build(int l, int r, int &rt){rt = tot++;cnt[rt] = 0;if(l == r) return;int mid = (l + r) >> 1;build(l, mid, ls[rt]);build(mid + 1, r, rs[rt]);
}void update(int last, int p, int l, int r, int &rt){rt = tot++;ls[rt] = ls[last];rs[rt] = rs[last];cnt[rt] = cnt[last] + 1;if(l == r){//printf("cnt = %d, l = %d, r = %d\n", cnt[rt], l, r);return ;}int mid = (l + r) >> 1;if(p <= mid) update(ls[last], p, l, mid, ls[rt]);else update(rs[last], p, mid + 1, r, rs[rt]);
}int query(int ss, int tt, int l, int r,int x){if(l == r) return x < l ? 0 : (cnt[tt] - cnt[ss]);int mid = (l + r) >> 1;if(x <= mid) return query(ls[ss], ls[tt], l, mid, x);else return cnt[ls[tt]] - cnt[ls[ss]] + query(rs[ss], rs[tt], mid + 1, r, x);
}int main(){int t; scanf("%d", &t);int cast = 0;while(t--){int n, m; scanf("%d %d", &n, &m);for(int i = 1; i <= n; i++){scanf(" %d", &a[i]);Hash[i] = a[i];}sort(Hash + 1, Hash + 1 + n);int Size = unique(Hash + 1, Hash + 1 + n) - Hash - 1;for(int i = 1; i <= n; i++){a[i] = lower_bound(Hash + 1, Hash + 1 + Size, a[i]) - Hash;}//for(int i = 1; i <= n; i++) printf("%d ", a[i]); cout << endl;tot = 0;build(1, Size, root[0]);for(int i = 1; i <= n; i++){update(root[i - 1], a[i], 1, Size, root[i]);}printf("Case %d:\n", ++cast);while(m--){int i, j, k;scanf("%d %d %d", &i, &j, &k);k = upper_bound(Hash + 1, Hash + 1 + Size, k) - Hash - 1;printf("%d\n", query(root[i], root[j + 1], 1, Size, k));}}return 0;
}

主席树模板 + 题解(无修改)相关推荐

  1. HDU4417 Super Mario (主席树模板)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  2. poj2823 线段树模板题 点修改(也可以用单调队列)

    这道题吧 没计算时间 因为给了那么多 一算还可以 就直接写了线段树,刘汝佳那本模板 然后!poj的g++比C++慢大约500ms.......g++tle,C++就过了 Sliding Window ...

  3. 解题报告:P3834 【模板】可持久化线段树 2(主席树)详解

    P3834 [模板]可持久化线段树 2(主席树) 题解 P3834 [[模板]可持久化线段树 2(主席树)] 1)静态求第k大数 可持久化线段树,不能用堆的方法存子结点了,所以用指针l表示左儿子r表示 ...

  4. 【用学校抄作业带你走进可持久化线段树(主席树)】可持久化线段树概念+全套模板+例题入门:[福利]可持久化线段树)

    我似乎很少写这种算法博客 可持久化线段树概念 概念介绍(类比帮助理解) 简单分析一下时间和空间复杂度(内容池) 模板 结构体变量 建树模板 单点修改模板 单点查询模板 区间修改模板(pushup) 区 ...

  5. P3834 【模板】可持久化线段树 1(主席树)

    传送门 如标题,主席树模板 稍微介绍一下主席树.. 主席树是很多个线段树的结合体 利用了单点修改不会更新太多节点的结论(反正这一题是这样..),后一个线段树借用前面线段树的节点,而对于更新的节点才开一 ...

  6. 主席树的各类模板(区间第k大数【动,静】,区间不同数的个数,区间=k的个数)...

    取板粗   好东西来的 1.(HDOJ2665)http://acm.hdu.edu.cn/showproblem.php?pid=2665 (POJ2104)http://poj.org/probl ...

  7. [THUPC2017]天天爱射击 题解(主席树)

    传送门:cogs2897 在网上搜了一圈,只有可怜的一篇题解,是整体二分的.其实这题可以不用整体二分(我不会整体二分). 二分的思想是,对于每块木板,可以二分它被打碎的时间,然后用数据结构来check ...

  8. 最详细的主席树(不修改,待修改) BZOJ 1901

    By Bartholomew 前置知识: 1.树状数组 2.线段树 主席树 模板是干什么的,其实就是询问区间第k大 不支持修改: 复杂度 O(nlogn) O ( n l o g n ) O(nlog ...

  9. 学习笔记:可持久化线段树(主席树):静态 + 动态

    学习笔记:可持久化线段树(主席树):静态 + 动态 前置知识: 线段树.线段树分享可以看:@秦淮岸.@ZYzzz.@妄想の岚がそこに 树状数组.\(BIT\)分享可以看:@T-Sherlock.Chi ...

最新文章

  1. docker注册表回传失败 群晖6.2_Glances实时监视群晖运行状况
  2. 实战:一键生成前后端代码,Mybatis-Plus代码生成器让我舒服了
  3. 制药企业正在基于AI与基因测序发现真菌更多药用价值
  4. print arraylist 显示的不是内容_泛型数组列表 java.util.ArrayListlt;Egt;
  5. 《番茄工作法图解》作者亲身讲解:这些最佳实践可以帮你筛选出那个最重要的任务...
  6. 【转】python类中super()和__init__()的区别
  7. android邮件发送几种方式
  8. keil debug如何在watch直接修改变量值_零基础学VBA:什么是VBA?如何编写和运行VBA代码?...
  9. SQL SERVER7应用
  10. 【计算机网络复习 数据链路层】3.3.1 差错控制(检错编码)
  11. 程序猿的数学:scratch篇
  12. [置顶] Android adb root权限
  13. 三、主流区块链技术特点及Hyperledger Fabric V1.0版本特点
  14. 计算机网络自顶向下-链路层
  15. c语言判断字符串合法标识符,HDU 2024 C语言合法标识符(以及一些关于输入和ctype.h的内容)...
  16. 【ubuntu】开机一直“/dev/sda3:clean, XXX files, XXXX blocks”解决方法
  17. 深入理解 Java 中 protected 修饰符
  18. 周育如的音标口诀大全_一年级汉语音标口诀记忆方法
  19. 二值化网络:BNN 论文阅读笔记
  20. java phaser 实用场景_猿灯塔-Phaser 使用介绍

热门文章

  1. 用安信可ESP32-G开发板制作一个简易路由器
  2. 主板开机电路故障的维修实例
  3. MATLAB R2016a版——改变Simulink中Scope输出波形的颜色
  4. 山西财经大学计算机好考吗,听说这是中国最难考的12所“财经”大学,山西财经大学入选,位列第十!...
  5. Git常见问题:Your branch and ‘xxx/xxx‘ have diverged
  6. cad导出pdf_如何将CAD图纸由DWG格式转换成PDF格式?_moinly
  7. Fisher线性判别分析
  8. java plugin_Java Plugin类代码示例
  9. 史上最详细sqlmap入门教程
  10. 根据设计稿设置rem大小,elementUI px转rem