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. hdu2141

    题目大意:输入三系列数A,B,C,输入一个数X,问是否在A,B,C中存在A[i]+B[j]+C[k]=X,存在输出YES,不存在输出NO. 本题若果采用暴力法那么复杂度为O(n3)显然会超时,如果把A ...

  2. C++ 变量的声明与定义的区别

    变量声明和定义的区别 我们在程序设计中,时时刻刻都用到变量的定义和变量的声明,可有些时候我们对这个概念不是很清楚,知道它是怎么用,但却不知是怎么一会事,下面我就简单的把他们的区别介绍如下:(望我的指点 ...

  3. mysql修改用户名和密码

    修改用户名 mysql> use mysql;  选择数据库Database changedmysql> update user set user="dns" wher ...

  4. <转>java编译问题:使用了未经检查或不安全的操作

    使用了未经检查或不安全的操作 在本人用editplus写java文件时碰到的问题.      源代码 import java.util.*; class collection{ public stat ...

  5. nodebeginer

    最近对node开始感兴趣,知乎上朴灵推荐入门书籍,goddy翻译的node beginner. 貌似大家对深入浅出node.js评价都不错,以后可以考虑入手看看. 一口气看完了node beginne ...

  6. linux基础命令整理

    1  显示当前工作目录                pwd 2  查看目录下的所有内容          ls        ls   -l   以列方式查看        ls  -a  显示所有 ...

  7. JS的单例模式

    维基百科对单例模式的介绍如下: 在应用单例模式时,生成单例的类必须保证只有一个实例的存在,很多时候整个系统只需要拥有一个全局对象,才有利于协调系统整体的行为.比如在整个系统的配置文件中,配置数据有一个 ...

  8. JavaWEB开发中的/到底代表什么

  9. access数据库 top语句失效解决方法

    使用查询语句  select   top 1  *  from  News  order  by  [PublicTime] desc   就不一定管用了,如果News表里面的PublicTime字段 ...

  10. ElasticSearch基本用法

    最大的特点: 1. 数据库的 database, 就是  index 2. 数据库的 table,  就是 tag 3. 不要使用browser, 使用curl来进行客户端操作.  否则会出现 jav ...