Poj 2104 K-th Number(主席树&&整体二分)
K-th Number
Time Limit: 20000MS Memory Limit: 65536K
Case Time Limit: 2000MS
Description
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.
Input
The 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 109 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).
Output
For 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.
Source
Northeastern Europe 2004, Northern Subregion
/*
主席树 静态第K小.
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100001
using namespace std;
int n,m,root[MAXN],cut,a[MAXN],s[MAXN];
struct data{int lc,rc,ans;}tree[MAXN*20];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int &now,int last,int l,int r,int x)
{
now=++cut;tree[now].ans=tree[last].ans+1;
tree[now].lc=tree[last].lc,tree[now].rc=tree[last].rc;
if(l==r) return ;
int mid=(l+r)>>1;
if(x<=mid) add(tree[now].lc,tree[last].lc,l,mid,x);
else add(tree[now].rc,tree[last].rc,mid+1,r,x);
return ;
}
int query(int L,int R,int l,int r,int x)
{
if(l==r) return l;
int p=tree[tree[R].lc].ans-tree[tree[L].lc].ans;//左树中数的个数.
int mid=(l+r)>>1;
if(p>=x) return query(tree[L].lc,tree[R].lc,l,mid,x);
else return query(tree[L].rc,tree[R].rc,mid+1,r,x-p);
}
int main()
{
int t;
int x,y,z;//t=read();
while(scanf("%d%d",&n,&m)!=EOF)
//(t--)
{
n=read(),m=read();
cut=0;memset(root,0,sizeof root);
for(int i=1;i<=n;i++) s[i]=a[i]=read();
sort(s+1,s+n+1);
for(int i=1;i<=n;i++)
{
int p=lower_bound(s+1,s+n+1,a[i])-s;
add(root[i],root[i-1],1,n,p);
}
while(m--)
{
x=read(),y=read(),z=read();
//z=(y-x+1)-z+1;
int p=query(root[x-1],root[y],1,n,z);
printf("%d\n",s[p]);
}
}
return 0;
}
/*
求静态区间第K小.
整体二分.
二分出一个答案然后统计贡献.
对多个操作同时处理.
然后使操作有序化.
树状数组维护一段值域区间内数的个数.
还是比较模糊orz.
*/
#include<iostream>
#include<cstdio>
#define MAXN 200001
#define INF 1e9
using namespace std;
struct data{int x,y,k,s,o,cut;}
q[MAXN],tmp1[MAXN],tmp2[MAXN];
int n,m,tot,s[MAXN],ans[MAXN],a[MAXN],tmp[MAXN];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int x,int z)
{
while(x<=n) s[x]+=z,x+=x&-x;
return ;
}
int getsum(int x)
{
int sum=0;
while(x>0) sum+=s[x],x-=x&-x;
return sum;
}
void slove(int head,int tail,int l,int r)
{
if(head>tail) return ;
if(l==r)
{
for(int i=head;i<=tail;i++)
if(q[i].o==3) ans[q[i].s]=l;
return ;
}
int mid=(l+r)>>1;
for(int i=head;i<=tail;i++)//统计贡献.
{
if(q[i].o==1&&q[i].y<=mid) add(q[i].x,1);
else if(q[i].o==3) tmp[i]=getsum(q[i].y)-getsum(q[i].x-1);
}
for(int i=head;i<=tail;i++)
if(q[i].y<=mid&&q[i].o==1) add(q[i].x,-1);
int l1=0,l2=0;
for(int i=head;i<=tail;i++)
{//检验 对于该操作找一个所属答案位置.
if(q[i].o==3)
{
if(q[i].cut+tmp[i]>=q[i].k) tmp1[++l1]=q[i];
//ans 偏大 放入[l,mid]区间查询.
else q[i].cut+=tmp[i],tmp2[++l2]=q[i];
//ans 偏小 放入[mid+1,r]区间查询.
}
else
{
if(q[i].y<=mid) tmp1[++l1]=q[i];
else tmp2[++l2]=q[i];
}
}
for(int i=1;i<=l1;i++) q[head+i-1]=tmp1[i];
for(int i=1;i<=l2;i++) q[head+l1+i-1]=tmp2[i];
slove(head,head+l1-1,l,mid),slove(head+l1,tail,mid+1,r);
return ;
}
int main()
{
int x,y,z,t=0;char ch[11];
n=read(),m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
q[++tot].x=i,q[tot].y=a[i];
q[tot].o=1,q[tot].s=0;
}
while(m--)
{
x=read(),y=read(),z=read();
q[++tot].x=x,q[tot].y=y,q[tot].k=z;
q[tot].o=3;q[tot].s=++t;
}
slove(1,tot,-INF,INF);
for(int i=1;i<=t;i++) printf("%d\n",ans[i]);
return 0;
}
Poj 2104 K-th Number(主席树&&整体二分)的更多相关文章
- 【POJ 2104】 K-th Number 主席树模板题
达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...
- 静态区间第k大(主席树)
POJ 2104为例(主席树入门题) 思想: 可持久化线段树,也叫作函数式线段树,也叫主席树(高大上). 可持久化数据结构(Persistent data structure):利用函数式编程的思想使 ...
- poj 2104 K-th Number 主席树+超级详细解释
poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...
- poj2104 k-th number 主席树入门讲解
poj2104 k-th number 主席树入门讲解 定义:主席树是一种可持久化的线段树 又叫函数式线段树 刚开始学是不是觉得很蒙逼啊 其实我也是 主席树说简单了 就是 保留你每一步操作完成之后 ...
- 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 大值是个经典的问题,可以使用 ...
- POJ 2104:K-th Number(主席树静态区间k大)
题目大意:对于一个序列,每次询问区间[l,r]的第k大树. 分析: 主席树模板题 program kthtree; type point=record l,r,s:longint; end; var ...
- SPOJ MKTHNUM & POJ 2104 - K-th Number - [主席树模板题]
题目链接:http://poj.org/problem?id=2104 Description You are working for Macrohard company in data struct ...
- poj 2104 K-th Number(主席树 视频)
K-th Number 题意: 给你一些数,让你求一个区间内,第k大的数是多少. 题解: 主席树第一题,看的qsc视频写的,戳戳戳 学到了unique函数,他的作用是:把相邻的重复的放到后面,返回值是 ...
随机推荐
- [v]Windows下Git安装指南
参考<Git权威指南>安装整理,图书配套网址参见[1] 1. Cygwin下安装配置Git 1. 在Windows下安装配置Git有2种不同的方案 (1)msysGit, (2)Cygwi ...
- javascript 之 Object.defineProperty
语法: Object.definePropty(obj,prop,descriptor); 参数: obj:要在其上定义属性的属性 prop:要定义或修改的属性的名称 desriptor:将被定义或修 ...
- Python之(scrapy)爬虫
一.Scrapy是Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘.监测和自动化测试. Scrapy吸 ...
- MySQL性能测试调优
MySQL性能测试调优 操作系统 基本操作 查看磁盘分区mount选项 $ mount 永久修改分区mount选项(系统重启后生效) 修改文件 /etc/fstab 中对应分区的mount optio ...
- iOS - App上架流程(复习+已用xcode8)
一.前言: 今天又要上架一款APP,顺便来复习一下APP上架流程 下面就来详细讲解一下具体流程步骤. 二.准备: 一个已付费的开发者账号(账号类型分为个人(Individual).公司(Company ...
- html中a标签的4个伪类样式
在CSS超链接的属性中,有四个连接方式:a:link a:hover a:visited a:acticve 之前在使用的时候一直是按照自认为的顺序中去写的,就是 L H V A的排序方式,然而有些时 ...
- Python:Shapefile矢量转化为GeoJSON格式
在最近的项目中,完成了许多python处理矢量数据的算法程序,比如缓冲区分析.叠置分析.统计分析等,主要用到的是GDAL/OGR库,很多功能都参照了此链接中的示例:http://pcjericks.g ...
- pygame安装遇到的坑
坑一:python版本冲突,电脑同时安装多个版本的python,由于每个都是python.exe,cmd命令窗口输入的python不一定是你想要的版本,所以最好还是安装单个版本即可. 坑二:由于电脑安 ...
- Python中@staticmethod和@classmethod的作用和区别
简单介绍一下两者的区别: 对于一般的函数test(x),它跟类和类的实例没有任何关系,直接调用test(x)即可 #!/usr/bin/python # -*- coding:utf-8 -*- de ...
- {T4模板}C# Net MVC+SqlServer=T4模板生成实体类并操作数据(DbHelper+DBManage)
1.ConnectionString,数据库链接 Web.config <configuration> <connectionStrings> <!-- 数据库 SQL ...