题解

又一次做这个题上一次用的是线段树上二分。这次用的是整体二分。结果:

(第一个是整体二分)

整体二分就是对于所有查询都二分一个值。然后根据能不能成立把询问修改分成两部分,然后第二部分继承第一部分的信息,然后这两部分继续递归。直到答案的值域为一个数,将这些询问的答案设成这个数就行了。

实现的时候,递归传4个参分别是询问的编号范围,和值域。

模板题还是要看代码理解。

 #include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=;
const int M=;
const int INF=0x3f3f3f3f;
int n,m,ans[M],tr[N],cnt;
struct query{
int x,y,k,id,type;
}q[N+M],c2[N+M],c1[N+M];
int lowbit(int x){
return x&-x;
}
void add(int x,int w){
for(int i=x;i<=n;i+=lowbit(i)){
if(i==)break;
tr[i]+=w;
}
}
int getsum(int x){
int ans=;
for(int i=x;i>=;i-=lowbit(i)){
if(i==)break;
ans+=tr[i];
}
return ans;
}
void solve(int l,int r,int L,int R){
if(l>r)return;
if(L==R){
for(int i=l;i<=r;i++){
if(q[i].type==)ans[q[i].id]=L;
}
return;
}
int mid=(L+R)>>;
int lnow=;int rnow=;
for(int i=l;i<=r;i++){
if(q[i].type==){
if(q[i].x<=mid){
add(q[i].id,q[i].y);
c1[++lnow]=q[i];
}
else c2[++rnow]=q[i];
}
else{
int tmp=getsum(q[i].y)-getsum(q[i].x-);
if(q[i].k<=tmp)c1[++lnow]=q[i];
else {
q[i].k-=tmp;
c2[++rnow]=q[i];
}
}
}
for(int i=;i<=lnow;i++){
if(c1[i].type==)add(c1[i].id,-c1[i].y);
}
for(int i=;i<=lnow;i++){
q[l+i-]=c1[i];
}
for(int i=;i<=rnow;i++){
q[l+lnow+i-]=c2[i];
}
solve(l,l+lnow-,L,mid);
solve(l+lnow,r,mid+,R);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
int x;
scanf("%d",&x);
q[i].id=i;q[i].x=x;q[i].type=;q[i].y=;
}
cnt=n;
for(int i=;i<=m;i++){
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
q[++cnt].id=i;q[cnt].x=x;q[cnt].y=y;q[cnt].k=k;q[cnt].type=;
}
solve(,cnt,-INF,INF);
for(int i=;i<=m;i++){
printf("%d\n",ans[i]);
}
return ;
}

POJ2104 K-th Number(整体二分)的更多相关文章

  1. POJ2104 K-th Number [整体二分]

    题目传送门 K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 69053   Accepted: 24 ...

  2. BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]

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

  3. BZOJ3110:[ZJOI2013]K大数查询(整体二分)

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

  4. BZOJ 3110 K大数查询 | 整体二分

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

  5. BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)

    题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...

  6. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  7. 静态区间第K小(整体二分、主席树)

    题目链接 题解 主席树入门题 但是这里给出整体二分解法 整体二分顾名思义是把所有操作放在一起二分 想想,如果求\([1-n]\)的第\(k\)小怎么二分求得? 我们可以二分答案\(k\), \(O(n ...

  8. ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112 题意: 求动态区间第K大. 分析: 把修改操作看成删除与增加 ...

  9. [ZJOI2013]K大数查询——整体二分

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是: 1 a b c:表示在第a个位置到第b个位置,每个位置加上一个数c 2 a b c:表示询问从第a个位置到第b个位置,第C大的数是多少. ...

随机推荐

  1. Cocos结构

    基类:CApplicationProtocol 纯虚函数virtual bool applicationDidFinishLaunching() = 0; CCApplication继承于CCAppl ...

  2. POJ 3268 Dijkstra+priority_queue或SPFA

    思路:正向建边,一遍Dijkstra,反向建边,再一遍Dijkstra.ans加在一起输出最大值. (SPFA也行--) // by SiriusRen #include <queue> ...

  3. asp.net DataTables

    无聊做一个,但是还是留下一些疑惑: 在控件中加入例如编辑,删除之类的按钮,而不是以行内元素呈现. 真实分页的实现方法. 要是有知道的朋友,希望指点一二. 下面只实现的功能: 隐藏列 冻结列 分页 列排 ...

  4. BAT 解密(四):配置中心、服务中心、异步技术细节

    在系列文章的第二篇文章< BAT解密(二):聊聊业务如何驱动技术发展 >中我们深入分析了互联网业务发展的一个特点:复杂性越来越高.复杂性增加的典型现象就是系统越来越多,当系统的数量增加到一 ...

  5. solarwinds之数据库

      1.              Orion配置向导     2.              连接数据库     3.              创建一个新的数据库     4.           ...

  6. SpringCloud学习笔记(6)----Spring Cloud Netflix之负载均衡-Ribbon的使用

    1. 什么是负责均衡? 负载均衡,就是分发请求流量到不同的服务器. 负载均衡一般分为两种 1. 服务器端负载均衡(nginx) 2. 客户端负载均衡(Ribbon) 2. 服务提供者(spring-c ...

  7. tomcat更改日志路径

    共有2个地方需要更改. 1.   tomcat/conf/logging.properties 步骤1--查找:grep logs logging.properties 步骤2--替换:sed -i ...

  8. 洛谷P2766 最长不下降子序列问题 网络流_DP

    Code: #include<cstdio> #include<iostream> #include<vector> #include<algorithm&g ...

  9. set集合关于set与set进行比较

    containsAll方法用来判断Set集合是否包含另一个集合中的全部内容. 语法  boolean containsAll(Collection<?> c) 返回值:如果Set集合包含参 ...

  10. kali(Ubuntu)右键添加idle打开方式

    IDLE可以说是Unix平台下Python的第一个集成开发环境(IDE) 命名行输入idle看idle是否已安装,没有则先安装 安装idle:apt-get install idle 安装完成后,命名 ...