传送门
找第 K K K大的时候把大于 m i d mid mid的标记为1.
如果把大于等于 m i d mid mid的标为1,那么有可能第 K K K大就是 m i d mid mid而当前统计的 1 1 1的个数大于 K K K(即有多个数为 m i d mid mid),于是答案会被往上调(为了减少 1 1 1的个数)。
也就是说答案范围变为 [ m i d + 1 , r ] [mid+1,r] [mid+1,r]。本来答案是 m i d mid mid。就出锅了。

比如说:3,4,4,4,5 求1~5中的第三大。(显然是4)
假设当前 m i d mid mid为4,于是数列变成0,1,1,1,1。
由于 4 > 3 4>3 4>3,那么二分的答案要上调,要把答案锁定在 [ m i d + 1 , 5 ] [mid+1,5] [mid+1,5]
于是得到了错误答案。

所以要把大于 m i d mid mid的标为1。

具体做法是:把操作按照答案范围分为两部分。
修改操作就按照修改值与 m i d mid mid大小比较,因为对应修改值只会在对应答案范围内产生贡献。

询问 k k k大就按照当前的操作顺序一步一步操作,然后遇见询问操作就统计区间和。和大了就要把答案上调。和小了就先减去这部分和(比它大的数的个数),然后把答案调小。

然后做完之后要把影响消回来,就是代码中区间减的部分。

50000次给50000个位置加上一个数。于是线段树统计sum爆int
输入有负数,注意读优

#include<bits/stdc++.h>
#define lc (root<<1)
#define rc (root<<1|1)
#define len(x) (T[x].r-T[x].l+1)
#define mid ((T[root].l+T[root].r)>>1)
#define ll long long
using namespace std;
const int maxn=5e4+10;
inline int read(){int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;
}
int n,m,op,a,b,c,cnt,ans[maxn];
struct que{int op,l,r,id;ll k;}Q[maxn],Q1[maxn],Q2[maxn];
struct node{int l,r;ll add,sum;}T[maxn<<2];
inline void pushup(int root){T[root].sum=T[lc].sum+T[rc].sum;}
inline void pushnow(int root,int val){T[root].add+=val;T[root].sum+=len(root)*val;
}
inline void pushdown(int root){if(T[root].add){pushnow(lc,T[root].add);pushnow(rc,T[root].add);T[root].add=0;}
}
inline void Update(int root,int l,int r,int val){if(l<=T[root].l&&T[root].r<=r)return pushnow(root,val);pushdown(root);if(l<=mid) Update(lc,l,r,val);if(r> mid) Update(rc,l,r,val);pushup(root);
}
inline ll Query(int root,int l,int r,ll ret=0){if(l<=T[root].l&&T[root].r<=r)return T[root].sum;pushdown(root);if(l<=mid) ret+=Query(lc,l,r);if(r> mid) ret+=Query(rc,l,r);return ret;
}
inline void build(int root,int l,int r){T[root].l=l,T[root].r=r;if(l==r) return;build(lc,l,mid),build(rc,mid+1,r);
}
inline void Solve(int l,int r,int S,int T){if(l>r||S>T) return;if(l==r){for(int i=S;i<=T;++i) if(Q[i].op==2)ans[Q[i].id]=l;return;}int Mid=(l+r)>>1,num1=0,num2=0;for(int i=S;i<=T;++i){if(Q[i].op==1){if(Q[i].k>Mid)Update(1,Q[i].l,Q[i].r,1),Q2[++num2]=Q[i];else Q1[++num1]=Q[i];}else{ll tmp=Query(1,Q[i].l,Q[i].r);if(tmp>=Q[i].k) Q2[++num2]=Q[i];else Q[i].k-=tmp,Q1[++num1]=Q[i];}}for(int i=1;i<=num2;++i) if(Q2[i].op==1) Update(1,Q2[i].l,Q2[i].r,-1);for(int i=1;i<=num1;++i) Q[S+i-1]=Q1[i];for(int i=1;i<=num2;++i) Q[S+num1+i-1]=Q2[i];Solve(l,Mid,S,S+num1-1),Solve(Mid+1,r,S+num1,T);
}
int main(){n=read(),m=read(),build(1,1,n);for(int i=1;i<=m;++i){Q[i].op=read(),Q[i].l=read(),Q[i].r=read(),Q[i].k=(ll)read();if(Q[i].op==2) Q[i].id=++cnt;}Solve(1,n,1,m);for(int i=1;i<=cnt;++i)printf("%d\n",ans[i]);
}

bzoj3110 K大数查询相关推荐

  1. BZOJ3110: [Zjoi2013]K大数查询

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

  2. bzoj3110 [Zjoi2013]K大数查询

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

  3. [BZOJ3110] [Zjoi2013]K大数查询

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

  4. python【蓝桥杯vip练习题库】ALGO-1区间k大数查询

    试题 算法训练 区间k大数查询 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示 ...

  5. 洛谷 P3332 [ZJOI2013]K大数查询 解题报告

    P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...

  6. 蓝桥杯-区间k大数查询(java)

    算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB问题描述给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个.输入格式第一行包含一个数n,表示序列长度.第二行包含n个 ...

  7. java:区间k大数查询

    试题 算法训练 区间k大数查询 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示 ...

  8. P3332 [ZJOI2013]K大数查询(整体二分做法)

    P3332 [ZJOI2013]K大数查询 题意: 题解: 利用整体二分来做,这个题和P3834 [模板]可持久化线段树 2的区别在于本题的修改是区间修改,所以将里面的树状数组改成线段树就行,区间修改 ...

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

    [ZJJOI2013]K大数查询 链接 luogu 思路 整体二分. 代码 #include <bits/stdc++.h> #define ll long long using name ...

最新文章

  1. FileReader采用的默认编码
  2. C# 深入浅出 委托与事件
  3. c语言ad采样程序思路,单片机AD采样程序及其寄存器讲解
  4. IOS开发基础之单文件上传基础最原始的方式
  5. ubuntu系统debootstrap的使用(构建一套基本的系统)
  6. 为什么JavaScript仅在IE中打开开发人员工具一次后才能工作?
  7. Android数据库hibernate框架
  8. rhel5 安装Oracle Database 10g Release 2(II)
  9. 枚举、自动装箱与注解(元数据)
  10. poj 1125 Floyd简单
  11. 通达信手机版分时图指标大全_通达信七彩虹分时图指标,出现红色柱时候可以大胆买入...
  12. php在线拍照代码,PHP+Javascript实现在线拍照功能实例_php技巧
  13. h5页面 html,h5页面和普通页面的区别是什么
  14. 再迎顶尖科学家,百度研究院为何如此吸引大师级AI人才?
  15. nofollow的使用以及作用
  16. 小爱同学指令大全_小爱同学指令
  17. [转载]autorun.inf病毒源代码
  18. 货拉拉数据治理平台建设实践
  19. java中 enum什么意思_enum在java中是什么意思
  20. 00无人机简介以及课程介绍2020-07-03

热门文章

  1. PACS系统源码:CT后处理技术之仿真内镜CTVE
  2. 怎样判断一个股权众筹项目是否靠谱?
  3. 【博学谷学习记录】超强总结,用心分享|大数据课程-学习第一周总结
  4. 语聊房app的开发以及运营思路
  5. StrokesPlus键盘按键表示
  6. Redis集群搭建加Springboot配置
  7. linux提取ttf字体轮廓,[TTF字体]提取TTF字体的轮廓(二)
  8. AI大模型未来将走向何方?广泛应用成首要挑战
  9. qemu服务器虚拟机与主机通讯,虚拟机:QEMU虚拟机和主机无线网络通讯设置
  10. python多大孩子可以学_少儿python教材适合多大的孩子