K-th Number
Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 31790   Accepted: 9838
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 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
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

这题是主席树裸题。

但是我却狂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大-主席树)的更多相关文章

  1. POJ 2104:K-th Number(整体二分)

    http://poj.org/problem?id=2104 题意:给出n个数和m个询问求区间第K小. 思路:以前用主席树做过,这次学整体二分来做.整体二分在yr大佬的指点下,终于大概懂了点了.对于二 ...

  2. 计蒜客 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 ...

  3. 【POJ】2104 K-th Number(区间k大+主席树)

    http://poj.org/problem?id=2104 裸题不说.主席树水过. #include <cstdio> #include <iostream> #includ ...

  4. POJ 2104:K-th Number(主席树静态区间k大)

    题目大意:对于一个序列,每次询问区间[l,r]的第k大树. 分析: 主席树模板题 program kthtree; type point=record l,r,s:longint; end; var ...

  5. POJ 2014.K-th Number 区间第k小 (归并树)

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

  6. HDU 2665.Kth number 区间第K小

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

  7. POJ2104 K-th Number —— 区间第k小 整体二分

    题目链接:https://vjudge.net/problem/POJ-2104 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Tota ...

  8. POJ 2104 求序列里第K大 主席树裸题

    给定一个n的序列,有m个询问 每次询问求l-r 里面第k大的数字是什么 只有询问,没有修改 可以用归并树和划分树(我都没学过..囧) 我是专门冲着弄主席树来的 对主席树的建树方式有点了解了,不过这题为 ...

  9. BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 418   Solved: 235 [ Submit][ ...

随机推荐

  1. Linux(Debain)环境安装WordPress

    一.相关组件安装 1. 安装Apache apt-get install apache2 安装完毕后浏览器 http://localhost/ 或者 http://127.0.0.1 出现It Wor ...

  2. unicode编码相互转换加密解密

    需求:把字符串转换成unicode编码加密. 也可以把unicode编码解密并分析出汉字字母数字字符各多少个. unicode编码 \u 后面是一个16进制编码,必要时需要进行转换. 看源码: 0 & ...

  3. ThinkPHP第十六天(redirect、join、视图模型)

    1.redirect /** * Action跳转(URL重定向) 支持指定模块和延时跳转 * access protected * @param string $url 跳转的URL表达式 * @p ...

  4. jquery获取多个checkbox的值异步提交给php

    html代码: <tr> <td><input type="checkbox" name="uid" value="&l ...

  5. Python之路Day2

    -->the start 养成好习惯,每次上课的内容都要写好笔记. 第二天内容主要是熟悉int.long.float.str.list.dict.tuple这几个类的内建方法. 对于Python ...

  6. python自学笔记(六)二进制与位移

    一.二进制 a = 1 bin(a)-->ob1  #python内置方法 ob 表示二进整型制格式 二.难缠符号 1.位移二进制的位 >> 右位移,想象成 切肉切去最后一位 例如 ...

  7. 一个Sqrt函数引发的血案(转)

    作者: 码农1946  来源: 博客园  发布时间: 2013-10-09 11:37  阅读: 4556 次  推荐: 41   原文链接   [收藏]   好吧,我承认我标题党了,不过既然你来了, ...

  8. MapReduce调度与执行原理之任务调度

    前言 :本文旨在理清在Hadoop中一个MapReduce作业(Job)在提交到框架后的整个生命周期过程,权作总结和日后参考,如有问题,请不吝赐教.本文不涉及Hadoop的架构设计,如有兴趣请参考相关 ...

  9. JAVA GUI学习 - JList列表、JScrollPane滚动条组件学习

    /** * 本例结合JList和JScrollPane共同使用 * @author Wfei * */ public class JListKnow extends JFrame { JList jL ...

  10. ADO.NET(一) 空间 ADO.NET结构 命名空间(车延禄) System.Data—— 所有的一般数据访问类 S(转载)

    ADO.NET(一) 空间   ADO.NET结构 命名空间(车延禄)System.Data—— 所有的一般数据访问类System.Data.Common—— 各个数据提供程序共享(或重写)的类Sys ...