题目传送门

题意:给你一个序列,长度为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. 【iOS】Error: Error Domain=PBErrorDomain Code=7 "Cannot connect to pasteboard server

    这几天在用 Swift 开发一个简单的键盘扩展,真机调试时遇到了这个问题,详细信息如下: ***[:] Could not save pasteboard named com.apple.UIKit. ...

  2. QTableView表格控件区域选择-自绘选择区域

    目录 一.开心一刻 二.概述 三.效果展示 四.实现思路 1.绘制区域 2.绘制边框 3.绘制 五.相关文章 原文链接:QTableView表格控件区域选择-自绘选择区域 一.开心一刻 陪完客户回到家 ...

  3. MyBatis之foreach

    foreach foreach 元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可以用在元素体内.它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符.这个元素是很智能的,它不会偶 ...

  4. 使用top查看进程和系统负载信息

    引言      使用top命令,可以查看正在运行的进程和系统负载信息,包括cpu负载.内存使用.各个进程所占系统资源等,top可以以一定频率更新这些统计信息.下面我们来学习top命令的具体使用方法. ...

  5. python编写环境(种类)

    python编写环境(种类) 官方推荐 cpython 转成C的字节码 jython转成Java的字节码 ironpython转成C#字节码 pypy转换成动态编译 开发快,运行快

  6. 素数筛法(Eratosthenes筛法)

    介绍 Eratosthenes筛法,又名埃氏筛法,对于求1~n区间内的素数,时间复杂度为n log n,对于10^6^ 以内的数比较合适,再超出此范围的就不建议用该方法了. 筛法的思想特别简单: 对于 ...

  7. 带你剖析WebGis的世界奥秘----Geojson数据加载(高级)

    前言:前两周我带你们分析了WebGis中关键步骤瓦片加载+点击事件(具体的看前两篇文章),下面呢,我带大家来看看Geojson的加载及其点击事件 Geojson数据解析 GeoJSON是一种对各种地理 ...

  8. NLP(十五)让模型来告诉你文本中的时间

    背景介绍   在文章NLP入门(十一)从文本中提取时间 中,笔者演示了如何利用分词.词性标注的方法从文本中获取时间.当时的想法比较简单快捷,只是利用了词性标注这个功能而已,因此,在某些地方,时间的识别 ...

  9. 直击根源:微信小程序中web-view再次刷新后页面需要退两次

    背景 在上一章(直击根源:vue项目微信小程序页面跳转web-view不刷新)解决了vue在小程序回退不刷新的问题之后,会引出了一个刷新的页面需要点击返回两次才能返回上一个页面 问题描述 在A页面从B ...

  10. 如何调教你的博客Episode2——移动端支持和UI美化

    这个系列的文章是我在搭建博客园博客时所经历的过程. 在上一期如何调教你的博客Episode1——修改整体样式中,我们通过添加CSS样式,修改了页面的总体布局.但将文章发出之后,博客的布局就出现问题了: ...