题目链接:https://vjudge.net/problem/POJ-2104

K-th Number
Time Limit: 20000MS   Memory Limit: 65536K
Total Submissions: 64110   Accepted: 22556
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>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 2e5+; struct node
{
int x, y, k, type, id;
};
node q[MAXN]; int n, m, c[MAXN];
int lowbit(int x) {return x&(-x);}
void add(int x, int val) {for(int i=x;i<=n;i+=lowbit(i)) c[i]+=val;}
int sum(int x) {int ret=; for(int i=x;i>;i-=lowbit(i))ret+=c[i]; return ret;} int ans[MAXN];
node q1[MAXN], q2[MAXN]; //两个桶
void solve(int l, int r, int ql, int qr) //二分答案
{
if(ql>qr) return; //!!
if(l==r) //当l==r时,即答案已明确
{
for(int i = ql; i<=qr; i++)
if(q[i].type==) ans[q[i].id] = l;
return;
} int mid = (l+r)>>; //写成 (l+r)/2会runtime error,不知为何
int t1 = , t2 = ;
for(int i = ql; i<=qr; i++) //枚举操作
{
if(q[i].type==)
{
if(q[i].y<=mid)
{
add(q[i].x, );
q1[++t1] = q[i];
}else q2[++t2] = q[i];
}
else
{
int pre = sum(q[i].y)-sum(q[i].x-);
if(pre>=q[i].k) q1[++t1] = q[i];
else
{
q[i].k -= pre;
q2[++t2] = q[i];
}
}
}
for(int i = ; i<=t1; i++) //撤回对线段树的操作
if(q1[i].type==) add(q1[i].x, -); for(int i = ; i<=t1; i++) q[ql+i-] = q1[i];
for(int i = ; i<=t2; i++) q[ql+t1+i-] = q2[i];
solve(l, mid, ql, ql+t1-);
solve(mid+, r, ql+t1, qr);
} int main()
{
while(scanf("%d%d",&n,&m)==)
{
int tot = ;
for(int i = ; i<=n; i++)
{
++tot;
scanf("%d", &q[tot].y);
q[tot].x = i; q[tot].type = ;
}
for(int i = ; i<=m; i++)
{
++tot;
scanf("%d%d%d", &q[tot].x,&q[tot].y,&q[tot].k);
q[tot].id = i; q[tot].type = ;
} memset(c, , sizeof(c));
solve(-MOD,MOD, ,tot);
for(int i = ; i<=m; i++)
printf("%d\n", ans[i]);
}
}

POJ2104 K-th Number —— 区间第k小 整体二分的更多相关文章

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

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

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

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

  3. 【XSY2720】区间第k小 整体二分 可持久化线段树

    题目描述 给你你个序列,每次求区间第\(k\)小的数. 本题中,如果一个数在询问区间中出现了超过\(w\)次,那么就把这个数视为\(n\). 强制在线. \(n\leq 100000,a_i<n ...

  4. 静态区间第k小 - 整体二分

    蒟蒻终于学会整体二分啦! 思路 实现 丑陋无比的代码 #include <bits/stdc++.h> using namespace std; const int N = 200005; ...

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

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

  6. BZOJ3110[Zjoi2013]K大数查询(树状数组+整体二分)

    3110 [Zjoi2013]K大数查询 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a ...

  7. bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】

    树套树: 约等于是个暴力了.以区间线段树的方式开一棵权值线段树,在权值线段树的每一个点上以动态开点的方式开一棵区间线段树. 结果非常惨烈(时限20s) #include<iostream> ...

  8. poj2104 K-th Number区间第k小值 主席树

    原来主席树就是可持久化线段树啊,刚知道,,, 作为一道裸题,还是必A的,然而一开始偷懒不写离散化跪了N多遍,后来在缪大的帮助下发现了这个问题,遂A之 ——又是这种破问题,实在不想说自己了 把n个数看成 ...

  9. POJ 2104 K-th Number(区间第k大数)(平方切割,归并树,划分树)

    题目链接: http://poj.org/problem? id=2104 解题思路: 由于查询的个数m非常大.朴素的求法无法在规定时间内求解. 因此应该选用合理的方式维护数据来做到高效地查询. 假设 ...

随机推荐

  1. C# Graphics

    Graphics.FillPie 方法 填充由一对坐标.一个宽度.一个高度以及两条射线指定的椭圆所定义的扇形区的内部. Graphics.FillPie (Brush, Int32, Int32, I ...

  2. Redis 在 Java 中的使用

    转:http://blog.csdn.net/jiangtao_st/article/details/8256610 一.下载jar包 https://github.com/xetorthio/jed ...

  3. 【工具类】Date、Long、String 类型互转

    开发常常遇到Date.Long.String 三种类型数据须要互转的问题.以此记录. public static void main(String[] args) throws ParseExcept ...

  4. mysql导出导入所有数据库

    导出所有数据库 mysqldump -uroot -p123456 --all-databases > /home/aa.sql 导入所有数据库 mysql -uroot -p123456 &l ...

  5. python多进程生成缩略图

    在img目录下7张图片 分别是 11.jpg 22.jpg 33.jpg 44.jpg 55.jpg 66.jpg 77.jpg #encoding=utf-8 import os import ti ...

  6. 转:几款主流pcb软件比较

      原理图设计软件:会ORCAD就可以了,支持的Netlist超多,基本是业界标准. PCB Layout 软件 1.Protel,现在推AltiumDesigner.国内低端设计的主流,国外基本没人 ...

  7. js 组合键监听ctrl + enter

    $(window).keydown(function (event) { // 监听esc键退出全屏 if (event.keyCode == 27) { } // 监听 Ctrl + Enter 可 ...

  8. 有关SQL注入的知识

    SQL注入攻击是非常令人讨厌的安全漏洞,是所有的web开发人员,不管是什么平台,技术,还是数据层,需要确信他们理解和防止的东西.不幸的是,开发人员往往不集中花点时间在这上面,以至他们的应用,更糟糕的是 ...

  9. JSP——Web应用

      1.EL表达式   2.jstl fmt功能说明     3.jsp 自定义标签     4.QR码————二维码等条码

  10. 8148之更换摄像头出现异常---REISZER OVERFLOW OCCURED: RESTARTING

    my iss config as: rsz_reg->SRC_VSZ  = 1079;//715;    rsz_reg->SRC_HSZ  = 1919;//1277; rszA_reg ...