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. ##DAY7 UINavigationController

    ##DAY7 UINavigationController #pragma mark ———————UINavigationController——————————— 概括: 导航视图控制器也是一个视 ...

  2. Java学习之抽象类的总结

    抽象类的特点:1,方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类必须也被abstract修饰.2,抽象类不可以被实例化.为什么?因为调用抽象方 ...

  3. Array.Add () and += in PowerShell

    $newArray = @() $newArray.Add("Hello") If I create a new array, and using the method Add() ...

  4. object-c 内存管理机制的学习

    1.内存的创建和释放 让我们以Object-c世界中最最简单的申请内存方式展开,谈谈关于一个对象的生命周期.首先创建一个对象: //“ClassName”是任何你想写的类名,比如NSString NS ...

  5. MySQL对于有大量重复数据表的处理方法

    需要在MySQL的一张innodb引擎的表(tableA)上添加一个唯一索引(idx_col1_u).但是对于每个key(col1)表中已经有大量重复数据.此时,做数据的手工清理,或者SQL处理是非常 ...

  6. js中this的深入研究

    this对象是函数在运行时由调用函数的对象决定的: 1.在全局对象中运行函数时,this等于window 2.当函数被作为某个对象的方法调用时, this等于那个对象. 需要注意的几点: 声明函数里的 ...

  7. asp.net传值

    asp.net页面传至几种方法 Response.Redirect (或称 Query String 方式.URL方式) Response.Redirect("WebForm5.aspx&q ...

  8. C#中类的运用(Eighth day)

    又到了总结知识的时刻了,今天在云和学院学习了类的运用,下面是今天所学知识的总结: 理论: 类的定义语法: [访问修饰符] class 类名 { 成员;  // 1.通过字段来描述类别信息的变量 ... ...

  9. [译]Stairway to Integration Services Level 4 - 增量更新数据

    在本文中, 我们说下增量更新数据:即将数据源中更新了的数据替换掉目标表中对应的数据. 更新代码 操作之前我们先把目标表e (dbo.Contact). 的数据改掉 Use AdventureWorks ...

  10. LeetCode 二叉树后序遍历(binary-tree-postorder-traversal)

    Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary t ...