POJ 2104(K-th Number-区间第k大-主席树)
|
K-th Number
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 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). Output
For each question output the answer to it --- the k-th number in sorted a[i...j] segment.
Sample Input 7 3 Sample Output 5 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
|
|||||||||
这题是主席树裸题。
但是我却狂T——
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
#include<map>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MAXN (100000+10)
#define MAXM (5000+10)
int n,m,a[MAXN],a2[MAXN];
struct node
{
node *ch[2];
int a,siz;
node(){ch[0]=ch[1]=NULL;siz=a=0;}
node(node *_ch0,node *_ch1,int _a,int _siz):a(_a),siz(_siz){ch[0]=_ch0,ch[1]=_ch1;}
void update()
{
siz=a;
if (ch[0]) siz+=ch[0]->siz;
if (ch[1]) siz+=ch[1]->siz;
}
}*null=new node(),*root[MAXN]={NULL};
void make_node(node *&y,node *&x,int l,int r,int t)
{
if (x==NULL) x=null;
y=new node();
int m=(l+r)>>1;
if (l==r)
{
*y=*x;
y->siz++;y->a++;
return;
}
if (t<=a2[m])
{
make_node(y->ch[0],x->ch[0],l,m,t);
y->ch[1]=x->ch[1];
y->update();
}
else
{
make_node(y->ch[1],x->ch[1],m+1,r,t);
y->ch[0]=x->ch[0];
y->update();
}
}
void find(node *&x1,node *&x2,int l,int r,int k)
{
if (x1==NULL) x1=null;
if (x2==NULL) x2=null;
if (l==r) {printf("%d\n",a2[l]);return;}
int m=(l+r)>>1;
int ls=0;
if (x2->ch[0]) ls+=x2->ch[0]->siz;
if (x1->ch[0]) ls-=x1->ch[0]->siz; if (ls>=k) find(x1->ch[0],x2->ch[0],l,m,k);
else find(x1->ch[1],x2->ch[1],m+1,r,k-ls);
}
int main()
{
freopen("poj2104.in","r",stdin);
null->ch[0]=null; null->ch[1]=null;
scanf("%d%d",&n,&m);
For(i,n) scanf("%d",&a[i]),a2[i]=a[i];
sort(a2+1,a2+1+n);
int size=unique(a2+1,a2+1+n)-(a2+1);
For(i,n)
{
make_node(root[i],root[i-1],1,size,a[i]);
}
For(i,m)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
find(root[l-1],root[r],1,size,k);
}
return 0;
}
于是在柯老师的教导下,我发现致使我狂T的因素是不断new 结点,于是我将结点事先用数组开好。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
#include<map>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MAXN (200000+10)
#define MAXM (200000+10)
int n,m,a[MAXN],a2[MAXN];
struct node
{
node *ch[2];
int a,siz;
node(){ch[0]=ch[1]=NULL;siz=a=0;}
void update()
{
siz=a;
if (ch[0]) siz+=ch[0]->siz;
if (ch[1]) siz+=ch[1]->siz;
}
}*null=new node(),*root[MAXN]={NULL},q[MAXN*9];
int q_s;
void make_node(node *&y,node *&x,int l,int r,int t)
{
if (x==NULL) x=null;
y=&q[++q_s];
*y=node();
int m=(l+r)>>1;
if (l==r)
{
*y=*x;
y->siz++;y->a++;
return;
}
if (t<=a2[m])
{
make_node(y->ch[0],x->ch[0],l,m,t);
y->ch[1]=x->ch[1];
y->update();
}
else
{
make_node(y->ch[1],x->ch[1],m+1,r,t);
y->ch[0]=x->ch[0];
y->update();
}
}
void find(node *&x1,node *&x2,int l,int r,int k)
{
if (x1==NULL) x1=null;
if (x2==NULL) x2=null;
if (l==r) {printf("%d\n",a2[l]);return;}
int m=(l+r)>>1;
int ls=0;
if (x2->ch[0]) ls+=x2->ch[0]->siz;
if (x1->ch[0]) ls-=x1->ch[0]->siz;
if (ls>=k) find(x1->ch[0],x2->ch[0],l,m,k);
else find(x1->ch[1],x2->ch[1],m+1,r,k-ls);
}
int main()
{
//freopen("hdu2665.in","r",stdin);
null->ch[0]=null; null->ch[1]=null;
q_s=0;
scanf("%d%d",&n,&m);
For(i,n) scanf("%d",&a[i]),a2[i]=a[i];
sort(a2+1,a2+1+n);
int size=unique(a2+1,a2+1+n)-(a2+1);
For(i,n)
{
make_node(root[i],root[i-1],1,size,a[i]);
}
For(i,m)
{
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
find(root[l-1],root[r],1,size,k);
}
return 0;
}
终于过了……伤不起……
POJ 2104(K-th Number-区间第k大-主席树)的更多相关文章
- POJ 2104:K-th Number(整体二分)
http://poj.org/problem?id=2104 题意:给出n个数和m个询问求区间第K小. 思路:以前用主席树做过,这次学整体二分来做.整体二分在yr大佬的指点下,终于大概懂了点了.对于二 ...
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- 【POJ】2104 K-th Number(区间k大+主席树)
http://poj.org/problem?id=2104 裸题不说.主席树水过. #include <cstdio> #include <iostream> #includ ...
- POJ 2104:K-th Number(主席树静态区间k大)
题目大意:对于一个序列,每次询问区间[l,r]的第k大树. 分析: 主席树模板题 program kthtree; type point=record l,r,s:longint; end; var ...
- POJ 2014.K-th Number 区间第k小 (归并树)
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 57543 Accepted: 19893 Ca ...
- HDU 2665.Kth number 区间第K小
Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- POJ2104 K-th Number —— 区间第k小 整体二分
题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS Memory Limit: 65536K Tota ...
- POJ 2104 求序列里第K大 主席树裸题
给定一个n的序列,有m个询问 每次询问求l-r 里面第k大的数字是什么 只有询问,没有修改 可以用归并树和划分树(我都没学过..囧) 我是专门冲着弄主席树来的 对主席树的建树方式有点了解了,不过这题为 ...
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 418 Solved: 235 [ Submit][ ...
随机推荐
- 利用Apperance协议定义View的全局外观
假设要定义一个全局的bkColor用于背景颜色 1.@property(nonatomic,strong)UIColor *bkColor UI_APPEARANCE_SELECTOR; 2.在下面方 ...
- Windows配置Python编程环境
1.安装Python https://www.python.org/ 2.修改环境变量 将安装python的路径加到path路径 3.配置notepad++ a. notepad++/运行/“运行”按 ...
- 获取json格式字符串的简单方法
有的时候需要找一些Json格式的字符串,可以打开任意一个网页进入到调试模式,然后看network相关的访问信息,就可以获取到. 比如: 在记笔记的时候,点击保存后,会发出一些请求,然后有相应的相应,任 ...
- ie6,ie7下设置overflow:auto下滚动条不起作用
今天遇到一个比较特殊的情况:ie6,ie7下设置overflow:auto下滚动条出来了但是滚动条不起任何作用,但在火狐,ie8,ie9,谷歌等浏览器下正常显示,解决方案:只需要加一个position ...
- PHP CI框架最近学到的内容
CI框架配置方面注意的细节 在config里面的database.php里面是和数据库配置相关的内容 $db['default'] = array( 'dsn' => '', 'hostname ...
- git版本控制的笔记
一.配置你的身份,提交代码时git就可以知道是谁提交的了 git config --global user.name "Tony" git config --global user ...
- wordpress模板制作第一课
一套完整的WordPress模板应至少具有如下文件: style.css : CSS(样式表)文件 index.php : 主页模板 archive.php : Archive/Category模板 ...
- 帝国cms数据表详细说明
表 名 解释 phome_ecms_infoclass_news 新闻采集规则记录表 phome_ecms_infotmp_news 采集临时表 phome_ecms_news 新闻主数据记录表 ph ...
- 导入jsp
<%@ page contentType="text/html;charset=UTF-8" %><%@ page isELIgnored="false ...
- DMA(STM32)
1.DMA:data memory access //实际的内存存储 注:DMA干活的时候是不须要CPU干涉的 2. ①内存(定义的变量)---外设(寄存器). ②内存---内存 ③外设---外 ...