题目传送门

题意:给你一个序列,长度为n,m次询问,询问一段区间的第k大。

题解:CDQ分治,对整个值域进行分治。每次取一个mid, 计算出整个区间内mid <= 的数目,如果 num >= k, 那么就可以第k大的数一定落在[ l, mid]之间, 否者就会落在 [mid+1, r]之间, 然后我们继续递归二分下去,直到 l == r 那么就找到第k大了。

代码:

 #include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<iostream>
#include<cstring>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 2e5 + ;
int n;
struct Node{
int op;
int L, R;
int x, id;
}A[N], lf[N], ri[N];
int tot = ;
void NowNode(int op, int L, int R, int x, int id){
++tot;
A[tot].op = op; A[tot].L = L; A[tot].R = R;
A[tot].x = x; A[tot].id = id;
}
int ans[N];
int tree[N];
int Mn = inf, Mx = ;
void Add(int x, int v){
for(int i = x; i <= n; i += i & (-i)){
tree[i] += v;
}
}
int Query(int x){
int ret = ;
for(int i = x; i; i -= i&(-i)){
ret += tree[i];
}
return ret;
}
void cdq(int Lval, int Rval, int st, int ed){
if(Lval > Rval || st > ed) return ;
if(Lval == Rval){
for(int i = st; i <= ed; i++)
if(A[i].op == ) ans[A[i].id] = Lval;
return ;
}
int mid = Lval + Rval >> ; int lsz = , rsz = ;
for(int i = st; i <= ed; i++){
int op = A[i].op, x = A[i].x, L = A[i].L, R = A[i].R, id = A[i].id;
if(op == ){
if(x <= mid){
Add(A[i].id, );
lf[++lsz] = A[i];
}
else ri[++rsz] = A[i];
}
else if(A[i].op == ){
int num = Query(R) - Query(L-);
if(num >= x) lf[++lsz] = A[i];
else {
A[i].x -= num;
ri[++rsz] = A[i];
}
}
}
for(int i = ; i <= lsz; i++) { if(lf[i].op == ) {
Add(lf[i].id, -);
}
A[st + i - ] = lf[i];
}
for(int i = ; i <= rsz; i++) A[st + lsz + i - ] = ri[i];
cdq(Lval, mid, st, st+lsz-);
cdq(mid+, Rval, st+lsz, ed);
}
int main(){
int m, val, l, r;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++){
scanf("%d", &val);
NowNode(,,,val,i);
Mn = min(Mn, val);
Mx = max(Mx, val);
}
for(int i = ; i <= m; i++){
scanf("%d%d%d", &l, &r, &val);
NowNode(,l,r,val,i);
}
cdq(Mn,Mx,,n+m);
for(int i = ; i <= m; i++){
printf("%d\n", ans[i]);
}
return ;
}

POJ-2104 K-th Number CDQ分治的更多相关文章

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

    感觉整体二分是个很有趣的东西. 在别人的博客上看到一句话 对于二分能够解决的询问,如果有多个,那么如果支持离线处理的话,那么就可以使用整体二分了 树套树写了一天还是WA着,调得焦头烂额,所以决定学cd ...

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

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

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

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

  4. 【POJ 2104】 K-th Number 主席树模板题

    达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...

  5. POJ 2104&HDU 2665 Kth number(主席树入门+离散化)

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

  6. K-th Number POJ - 2104

    K-th Number POJ - 2104 You are working for Macrohard company in data structures department. After fa ...

  7. POJ 2104 K-th Number【整体二分 + 树状数组】

    本来只是想学一下CDQ,还是先把整体二分搞懂一点. 这题窝几个月前分别用划分树,树套树,主席树和挑战上介绍的分桶法实现了一发(然而现在都忘得差不多了) 最快的是划分树,其次是主席树,然后是树套树,还有 ...

  8. K-th Number POJ - 2104 划分树

    K-th Number You are working for Macrohard company in data structures department. After failing your ...

  9. poj 2104 K-th Number 主席树+超级详细解释

    poj 2104 K-th Number 主席树+超级详细解释 传送门:K-th Number 题目大意:给出一段数列,让你求[L,R]区间内第几大的数字! 在这里先介绍一下主席树! 如果想了解什么是 ...

随机推荐

  1. 显示Mac隐藏文件的命令:

    设置查看隐藏文件的方法如下:打开终端,输入命名 显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles -bool true 隐藏 ...

  2. Android开发进阶——自定义View的使用及其原理探索

    在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...

  3. SpringBoot的yml配置

    Spring Boot的yml配置 #开发配置 spring: data: solr: host: http://localhost:6789/solr/mote mvc: view: # 页面默认前 ...

  4. CodeForces 372 A. Counting Kangaroos is Fun

    题意,有n只袋鼠,没每只袋鼠有个袋子,大小为si,一个袋鼠可以进入另外一个袋鼠的袋子里面,当且仅当另一个袋鼠的袋子是他的二倍或二倍一上,然后中国袋鼠就是不可见的,不能出现多个袋鼠嵌套的情况.让你求最少 ...

  5. JAVA基础知识(九)Java 异常

    Throwable是Error和Exception的基类 Exception(异常) :是程序本身可以处理的异常. Error(错误): 是程序无法处理的错误.这些错误表示故障发生于虚拟机自身.或者发 ...

  6. 从MySQL迁移到MariaDB(CentOS)

    MySQL是世界上最流行的开源关系数据库.原来 MariaDB 的设计初衷之一就是完全兼容 MySQL,包括 API 和客户端协议,使之能轻松成为 MySQL 的代替品.MariaDB 与 MySQL ...

  7. 认识Redies

    既然是作为了解性文章,那必然不会做很深入的解读.深入的解读以后会加上. 我们先来回答两个问题.通过这两个问题来开始我们的Redies入门之旅. Redies是什么? Redies有什么作用? Redi ...

  8. linux100day(day3)--常用文本处理命令和vim文本编辑器

    今天,来介绍几个常用文本处理命令和vim文本编辑器 day3--常用文本处理命令和vim文本编辑器 col,用于过滤控制字符,-b过滤掉所有控制字符,这个命令并不常用,但可以使用man 命令名| co ...

  9. virtualenv使用和virtualenvwrapper使用笔记

    virtualenv使用笔记 1.安装 pip install virtualenv 2.创建虚拟环境 virtualenv env //对于python2.7,该虚拟环境env必须在英文目录路径下 ...

  10. Windows Server 2008 R2服务器内存使用率过高,但与任务管理器中进程占用内存和不一致

    系统环境: Windows Server 2008 R2 + Sql Server 2008 R2   问题描述: Windows Server 2008 R2系统内存占用率过大,而在任务管理器中各进 ...