Online Judge 2014 K-th Number -主席树
You are working for Macrohard company in data structures department. After failing your previous task about key insertion you were asked to write a new data structure that would be able to return quickly k-th order statistics in the array segment.
That is, given an array a[1...n] of different integer numbers, your program must answer a series of questions Q(i, j, k) in the form: "What would be the k-th number in a[i...j] segment, if this segment was sorted?"
For example, consider the array a = (1, 5, 2, 6, 3, 7, 4). Let the question be Q(2, 5, 3). The segment a[2...5] is (5, 2, 6, 3). If we sort this segment, we get (2, 3, 5, 6), the third number is 5, and therefore the answer to the question is 5.InputThe first line of the input file contains n --- the size of the array, and m --- the number of questions to answer (1 <= n <= 100 000, 1 <= m <= 5 000).
The second line contains n different integer numbers not exceeding 10 9 by their absolute values --- the array for which the answers should be given.
The following m lines contain question descriptions, each description consists of three numbers: i, j, and k (1 <= i <= j <= n, 1 <= k <= j - i + 1) and represents the question Q(i, j, k).OutputFor each question output the answer to it --- the k-th number in sorted a[i...j] segment.
Sample Input
7 3
1 5 2 6 3 7 4
2 5 3
4 4 1
1 7 3
Sample Output
5
6
3
Hint
This problem has huge input,so please use c-style input(scanf,printf),or you may got time limit exceed.
很裸的主席树模板题。不知道可不可以用O(n1.5log2n)的莫队加平衡树来做。
如果用下面这段代码去过poj的话会T掉,如果不是用new动态分配内存而是直接分配一个数组,在数组中储存所有节点可能就可以过了。
Code
/**
* OpenJudge
* Bailian#2104
* Accepted
* Time:2247ms
* Memory:65536k
*/
#include<iostream>
#include<fstream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef bool boolean;
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline void readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -){
ungetc(x, stdin);
return;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
} typedef class SegTreeNode{
public:
int s; //size
SegTreeNode *left, *right;
SegTreeNode():left(NULL), right(NULL), s(){ }
void pushUp(){
this->s += this->left->s + this->right->s;
}
}SegTreeNode; typedef class SegTree{
public:
SegTreeNode* root;
SegTree():root(NULL){ }
SegTree(int size, int val){
build(root, , size, val);
}
SegTree(SegTreeNode* root):root(root){ } void build(SegTreeNode*& node, int from, int end, int val){
node = new SegTreeNode();
if(from == end){
node->s = (val == from) ? () : ();
return;
}
int mid = (from + end) >> ;
build(node->left, from, mid, val);
build(node->right, mid + , end, val);
node->pushUp();
}
}SegTree; typedef class Pair{
public:
int data;
int index;
Pair(const int data = , const int index = ):data(data), index(index){ }
boolean operator < (Pair another) const {
return data < another.data;
}
}Pair; typedef class ChairTree{ //主席树
public:
SegTree* st;
int* discrete;
map<int, int> to;
int len;
ChairTree():st(NULL), discrete(NULL){ }
ChairTree(int* lis, int len):len(len){
discrete = new int[(const int)(len + )];
memcpy(discrete, lis, sizeof(int) * (len + ));
sort(discrete + , discrete + len + );
for(int i = ; i <= len; i++)
to[discrete[i]] = i;
st = new SegTree[(const int)(len + )];
st[] = SegTree(len, );
for(int i = ; i <= len; i++){
st[i] = SegTree();
appendSegTree(st[i].root, st[i - ].root, , len, to[lis[i]]);
}
} void appendSegTree(SegTreeNode*& node, SegTreeNode*& before, int from, int end, int val){
node = new SegTreeNode();
if(from == end){
node->s = ;
return;
}
int mid = (from + end) >> ;
if(val <= mid){
node->right = before->right;
appendSegTree(node->left, before->left, from, mid, val);
}else{
node->left = before->left;
appendSegTree(node->right, before->right, mid + , end, val);
}
node->pushUp();
} int query(int l, int r, SegTreeNode*& left, SegTreeNode*& right, int k){
if(l == r){
return l;
}
int ls = left->left->s - right->left->s;
int mid = (l + r) >> ;
if(ls >= k) return query(l, mid, left->left, right->left, k);
return query(mid + , r, left->right, right->right, k - ls);
} int query(int from, int end, int k){
return discrete[query(, len, st[end].root, st[from - ].root, k)];
}
}ChairTree; int n, m;
ChairTree ct;
int *lis; inline void init(){
readInteger(n);
readInteger(m);
lis = new int[(const int)(n + )];
for(int i = ; i <= n; i++){
readInteger(lis[i]);
}
ct = ChairTree(lis, n);
} inline void solve(){
int l, r, k;
while(m--){
readInteger(l);
readInteger(r);
readInteger(k);
int res = ct.query(l, r, k);
printf("%d\n", res);
}
} int main(){
init();
solve();
return ;
}
Online Judge 2014 K-th Number -主席树的更多相关文章
- poj2104 k-th number 主席树入门讲解
poj2104 k-th number 主席树入门讲解 定义:主席树是一种可持久化的线段树 又叫函数式线段树 刚开始学是不是觉得很蒙逼啊 其实我也是 主席树说简单了 就是 保留你每一步操作完成之后 ...
- poj 2104 K-th Number 主席树+超级详细解释
poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...
- POJ 2104 K-th Number 主席树(区间第k大)
题目链接: http://poj.org/problem?id=2104 K-th Number Time Limit: 20000MSMemory Limit: 65536K 问题描述 You ar ...
- POJ 2104 K-th Number ( 求取区间 K 大值 || 主席树 || 离线线段树)
题意 : 给出一个含有 N 个数的序列,然后有 M 次问询,每次问询包含 ( L, R, K ) 要求你给出 L 到 R 这个区间的第 K 大是几 分析 : 求取区间 K 大值是个经典的问题,可以使用 ...
- poj2104 K-th Number区间第k小值 主席树
原来主席树就是可持久化线段树啊,刚知道,,, 作为一道裸题,还是必A的,然而一开始偷懒不写离散化跪了N多遍,后来在缪大的帮助下发现了这个问题,遂A之 ——又是这种破问题,实在不想说自己了 把n个数看成 ...
- POJ2104 K-th Number[主席树]【学习笔记】
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 51440 Accepted: 17594 Ca ...
- [poj2104] K-th Number (主席树)
主席树 Description You are working for Macrohard company in data structures department. After failing y ...
- poj 2104 K-th Number(主席树 视频)
K-th Number 题意: 给你一些数,让你求一个区间内,第k大的数是多少. 题解: 主席树第一题,看的qsc视频写的,戳戳戳 学到了unique函数,他的作用是:把相邻的重复的放到后面,返回值是 ...
- 主席树:POJ2104 K-th Number (主席树模板题)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 44952 Accepted: 14951 Ca ...
随机推荐
- CCCC L2 部落 L3社交集群
https://www.patest.cn/contests/gplt/L2-024 题解:部落是并查集模板题. 社交集群用并查集暴力有23分 坑:写了半天,发现自己并查集没怎么学明白,现在才搞懂: ...
- 停机问题(英语:halting problem)是逻辑数学中可计算性理论的一个问题。通俗地说,停机问题就是判断任意一个程序是否能在有限的时间之内结束运行的问题。该问题等价于如下的判定问题:是否存在一个程序P,对于任意输入的程序w,能够判断w会在有限时间内结束或者死循环。
htps://baike.baidu.com/item/停机问题/4131067?fr=aladdin 理发师悖论:村子里有个理发师,这个理发师有条原则是,对于村里所有人,当且仅当这个人不自己理发,理 ...
- 经典的DOS小命令 for 网络 nbtstat
--网络scanner · 1.最基本,最常用的,测试物理网络的 ping 192.168.10.59 -t ,参数-t是等待用户去中断测试 2.查看DNS(对猫用户),还是比较有用处的 A.Win9 ...
- 启动spark-shell
$cd /app/hadoop/spark-1.1.0/bin $spark-shell --master spark://SPARK02:7077 --executor-memory 500m 特别 ...
- 统计词语频率保存到xls
import json import jieba.analyse as anl import xlwt # 获取待统计的文本内容 # 打开文件 f = open('zhilian.json', 'r' ...
- php页面获取数据库中的数据
<!DOCTYPE HTML><html> <head> <meta charset="utf-8" /> ...
- hiredis(Synchronous API)
hiredis是一个小型的client端的c库.它只增加了最小对协议的支持,同时它用一个高级别的printf-alike API为了绑定各种redis命令.除了支持发送和接收命令,它还支持对流的解析. ...
- find the safest road(弗洛伊德)
http://acm.hdu.edu.cn/showproblem.php?pid=1596 #include <iostream> #include <stdio.h> #i ...
- 【转】SVM入门(一)SVM的八股简介
(一)SVM的八股简介 支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本.非线性及高维模式识别中表现出许多特有的优势,并能够 ...
- eigen quick reference
参考: http://eigen.tuxfamily.org/dox/AsciiQuickReference.txt // A simple quickref for Eigen. Add anyth ...