Luogu P2617 Dynamic Rankings(整体二分)
题目
动态区间第K小模板题。
一个非常可行的办法是BIT套动态开点权值SegTree,但是它跑的实在太慢了。
然后由于这题并没有强制在线,所以我们可以使用整体二分来吊打树套树。
当然如果强制在线的话就只能够用大常数的树套树了。
这里稍微结合这道题讲一下整体二分吧。
我们把所有询问加修改(统称为操作)按时间顺序排好,然后一起二分答案。
对于一个操作区间\([ql,qr]\)和答案\(mid\),我们顺序遍历所有操作。
将所有能在当前情况下产生影响的修改进行执行并放到左操作区间,否则直接放到右操作区间。
将所有答案\(\le mid\)的询问放到左操作区间,否则在处理完当前执行的操作的影响之后放到右区间。
然后把我们用来维护修改求答案的数据结构还原。并对左操作区间和右操作区间分别分治。
因为我们考虑这样一个事实:不管我们分治到了什么时候,所有操作区间中的操作还是按时间排序的。
因此我们可以直接顺序遍历操作来修改和查询。
而在考虑左操作区间的修改对右操作区间的查询的影响时,我们可以直接在遍历的过程中进行修改。
在这个题目中,我们二分出来一个答案\(mid\),那么我们把所有\(\le mid\)的数视作\(1\),否则视作\(0\),那么我们就可以根据前缀和来判断答案是\(\le mid\)还是\(>mid\)了。
我们可以将初始序列看做在某个位置插入一个数,修改看做在某个位置把原来的数删掉再插入一个新的。
那么我们就可以使用BIT来支持单点修改和区间查询。
注意在清零BIT的时候是要撤销而非memset,否则复杂度原地升天。
#include<bits/stdc++.h>
using namespace std;
namespace IO
{
char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
void Flush(){fwrite(obuf,1,oS-obuf,stdout),oS=obuf;}
void Put(char x){*oS++=x;if(oS==oT)Flush();}
char fetch(){char c=Get();while(!isupper(c))c=Get();return c;}
int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
void write(int x){int top=0;if(!x)Put('0');while(x)st[++top]=(x%10)+48,x/=10;while(top)Put(st[top--]);Put('\n');}
}
using namespace IO;
const int N=100007;
struct node{int opt,l,r,x,id;}q[N*3],q1[N*3],q2[N*3];
int n,m,Q,tot,a[N],h[N<<1],t[N],ans[N*3];
void add(int p,int v){for(;p<=n;p+=p&-p)t[p]+=v;}
int ask(int p){int s=0;for(;p;p^=p&-p)s+=t[p];return s;}
void solve(int ql,int qr,int vl,int vr)
{
if(ql>qr) return ;
if(vl==vr)
{
for(int i=ql;i<=qr;++i) if(q[i].opt==2) ans[q[i].id]=h[vl];
return ;
}
int mid=(vl+vr)>>1,l=0,r=0;
for(int i=ql,k;i<=qr;++i)
if(q[i].opt==1)
if(q[i].r<=mid) add(q[i].l,q[i].x),q1[l++]=q[i];
else q2[r++]=q[i];
else
if((k=ask(q[i].r)-ask(q[i].l-1))>=q[i].x) q1[l++]=q[i];
else q[i].x-=k,q2[r++]=q[i];
for(int i=0;i<l;++i) if(q1[i].opt==1) add(q1[i].l,-q1[i].x);
memcpy(q+ql,q1,l*(sizeof(node))),memcpy(q+ql+l,q2,r*(sizeof(node)));
solve(ql,ql+l-1,vl,mid),solve(ql+l,qr,mid+1,vr);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;++i) h[++tot]=a[i]=read(),q[++Q]=(node){1,i,a[i],1,Q};
for(int i=1,x,l,r;i<=m;++i)
if(fetch()=='Q') l=read(),r=read(),x=read(),q[++Q]=(node){2,l,r,x,Q};
else l=read(),h[++tot]=r=read(),q[++Q]=(node){1,l,a[l],-1,Q},q[++Q]=(node){1,l,a[l]=r,1,Q};
sort(h+1,h+tot+1),tot=unique(h+1,h+tot+1)-h-1;
for(int i=1;i<=n;++i) a[i]=lower_bound(h+1,h+tot+1,a[i])-h;
for(int i=1;i<=Q;++i) if(q[i].opt==1) q[i].r=lower_bound(h+1,h+tot+1,q[i].r)-h;
solve(1,Q,1,tot);
for(int i=1;i<=Q;++i) if(ans[i]) write(ans[i]);
return Flush(),0;
}
Luogu P2617 Dynamic Rankings(整体二分)的更多相关文章
- 洛谷$P2617\ Dynamic\ Rankings$ 整体二分
正解:整体二分 解题报告: 传送门$w$ 阿查询带修区间第$k$小不显然整体二分板子呗,,, 就考虑先按时间戳排序(,,,其实并不需要读入的时候就按着时间戳排的鸭$QwQ$ 每次二分出$mid$先把所 ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- 【BZOJ1901】Dynamic Rankings [整体二分]
Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一个含 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——整体二分
[题目分析] 上次用树状数组套主席树做的,这次用整体二分去水. 把所有的查询的结果一起进行二分,思路很好. [代码] #include <cstdio> #include <cstr ...
- BZOJ1901: Zju2112 Dynamic Rankings(整体二分 树状数组)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9094 Solved: 3808[Submit][Status][Discuss] Descript ...
- ZOJ2112 Dynamic Rankings(整体二分)
今天学习了一个奇技淫巧--整体二分.关于整体二分的一些理论性的东西,可以参见XRH的<浅谈数据结构题的几个非经典解法>.然后下面是一些个人的心得体会吧,写下来希望加深一下自己的理解,或者如 ...
- BZOJ 1901 Dynamic Rankings (整体二分+树状数组)
题目大意:略 洛谷传送门 这道题在洛谷上数据比较强 貌似这个题比较常见的写法是树状数组套主席树,动态修改 我写的是整体二分 一开始的序列全都视为插入 对于修改操作,把它拆分成插入和删除两个操作 像$C ...
- luogu P2617 Dynamic Rankings && bzoj 1901 (带修改区间第k大)
链接:https://www.luogu.org/problemnew/show/P2617 思路: 如果直接在主席树上修改的话,每次修改都会对后面所有的树造成影响,一次修改的复杂度就会变成 : n* ...
- Luogu P2617 Dynamic Rankings
带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了. 核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然 ...
随机推荐
- MapBox
MapBox的地图API大家用过吗 用作网站或者APP的底图,就不用自己架设地图服务器了 发布自己的地图了 这跟Google Map是一样的道理,类似的还有天地图,高德,百度地图API等等. 属于前端 ...
- jQuery的replaceWith()函数用法详解
replaceWith,替换元素 replaceWith() 方法将选择的元素的内容替换为其他内容. 我们先在先看一个实例 <!DOCTYPE html> <html> < ...
- HNOI2012排队
排列组合题(本文A(n,m)表示从n个元素里选m个的排列数). 首先,老师和女生有不能相邻的限制条件,应该用插空法.而且老师人数较少且固定,把老师和男生进行混合,对女生用插空. 我先来一手错误做法,n ...
- InnoDB记录存储结构
InnoDB是一个将数据存储到磁盘上的存储引擎.对于更新/写入的数据,先将数据从磁盘中加载到内存,更新后再将数据刷新到磁盘. 行格式 而磁盘与内存交互的数据,InnoDB采取将数据分为若干页,一页一般 ...
- python函数(一)
今天记一下学到的python函数相关知识. 目录: 1.函数简介 2.函数定义 3.函数参数 第一部分:函数简介 我们在编程过程中往往会碰到这样的事情-----很多地方都用到了相同的一段代码.虽 ...
- iOS 修改打包后的.ipa应用名字
一.修改应用的名字 二.重新签名 下面详细介绍介绍两个步骤: 1.修改应用的名字: 1).解压.ipa文件,在Payload文件夹下有一个.app文件(如下图:)选中.app文件,右键点击“显示包内容 ...
- 按下home键,重新打开,应用重启
其实不是重启,只是重新打开了luncher的那个activity.只要通过判断把它finish,就会显示按下home键前的页面. 解决方法: 在重启的页面中加入一下代码,注意加在setContentV ...
- 阶段3 3.SpringMVC·_05.文件上传_6 文件上传之跨服务器上传代码
参数HttpServletRequest也可以删掉 扩服务器的代码 注意选择jersey包下的 拿到文件资源.put过去. 最终代码 重新部署springMvc 图片服务器正常运行 客户端服务器 服 ...
- linux常用命令(20)用SecureCRT来上传和下载文件
用SSH管理linux服务器时经常需要远程与本地之间交互文件.而直接用SecureCRT自带的上传下载功能无疑是最方便的,SecureCRT下的文件传输协议有ASCII.Xmodem.Zmodem. ...
- 007. Reverse Integer
题目链接:https://leetcode.com/problems/reverse-integer/description/ Given a 32-bit signed integer, rever ...