HDU - 5412 CRB and Queries (整体二分)
动态区间第k小,但是这道题的话用主席树+树状数组套线段树的空间复杂度是O(nlog2n)会爆掉。
另一种替代的方法是用树状数组套平衡树,空间复杂度降到了O(nlogn),但我感觉平衡树是个挺恶心的东西,而且时间复杂度是O(nlog3n),比主席树还多了个logn。
最高效的方法是用一个叫整体二分的东西算法,它的基本思想是这样的:
假设当前所有查询的答案范围都在[l,r]之间,设mid=(l+r)/2,那么我们只处理所有修改后的值在[l,mid]中的修改操作,把不需要执行的修改操作全部扔到后半区间,那么对于每个询问操作都可以知道它的答案是在[l,mid]之间还是(mid+1,r]之间,这样就把所有的询问划分到了两个独立的区间,然后递归处理即可。本质上是将原序列转化成01序列,这样处理起来就方便多了。与CDQ分治较为类似,是个很神奇的算法。
空间复杂度O(n),时间复杂度O(nlog2n)
#include<bits/stdc++.h> using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+;
struct QR {
int f,l,r,k,u,x,dx;
} qr[N<<]; int a[N],c[N],b[N<<],lq[N<<],rq[N<<],nq,tot,ans[N],n,m;
int lowbit(int x) {return x&-x;}
void add(int u,int x) {
for(; u<=n; u+=lowbit(u))c[u]+=x;
}
int query(int u) {
int ret=;
for(; u; u-=lowbit(u))ret+=c[u];
return ret;
} 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(qr[b[i]].f)ans[qr[b[i]].u]=l;
return;
}
int nl=,nr=,mid=(l+r)>>;
for(int i=L; i<=R; ++i) {
if(!qr[b[i]].f) {
if(qr[b[i]].x<=mid)add(qr[b[i]].u,qr[b[i]].dx),lq[nl++]=b[i];
else rq[nr++]=b[i];
} else {
int t=query(qr[b[i]].r)-query(qr[b[i]].l-);
if(qr[b[i]].k<=t)lq[nl++]=b[i];
else qr[b[i]].k-=t,rq[nr++]=b[i];
}
}
for(int i=; i<nl; ++i)if(!qr[lq[i]].f)add(qr[lq[i]].u,-qr[lq[i]].dx);
for(int i=; i<nl; ++i)b[L+i]=lq[i];
for(int i=; i<nr; ++i)b[L+nl+i]=rq[i];
solve(l,mid,L,L+nl-);
solve(mid+,r,L+nl,R);
} int main() {
while(scanf("%d",&n)==) {
nq=tot=;
memset(c,,sizeof c);
int maxn=;
for(int i=; i<=n; ++i) {
scanf("%d",&a[i]);
maxn=max(maxn,a[i]);
qr[nq++]=(QR) {,,,,i,a[i],};
}
scanf("%d",&m);
while(m--) {
int f;
scanf("%d",&f);
if(f==) {
int u,x;
scanf("%d%d",&u,&x);
qr[nq++]=(QR) {,,,,u,a[u],-};
qr[nq++]=(QR) {,,,,u,a[u]=x,};
maxn=max(maxn,a[u]);
} else {
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
qr[nq++]=(QR) {,l,r,k,tot++,,};
}
}
for(int i=; i<nq; ++i)b[i]=i;
solve(,maxn,,nq-);
for(int i=; i<tot; ++i)printf("%d\n",ans[i]);
}
return ;
}
HDU - 5412 CRB and Queries (整体二分)的更多相关文章
- hdu 5412 CRB and Queries(整体二分)
题意 动态区间第k大 (n<=100000,m<=100000) 题解 整体二分的应用. 与静态相比差别不是很大.(和CDQ还有点像)所以直接上代码. #include<iostre ...
- hdu 5412 CRB and Queries
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5412 CRB and Queries Description There are $N$ boys i ...
- Hdu CRB and Queries(整体二分)
CRB and Queries Time Limit: 6000 MS Memory Limit: 131072 K Problem Description There are N boys in C ...
- HDU5412 CRB and Queries 整体二分
传送门 刚觉得最近写代码比较顺畅没什么Bug,cdq分治真是我的一个噩梦.. 整体二分模板题,带修改的区间第k小. vjudge不知抽什么风,用不了,hdu忘了密码了一直在那里各种试,难受.. 写得比 ...
- HDU 5412——CRB and Queries——————【线段树套Treap(并没有AC)】
CRB and Queries Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- 2015 Multi-University Training Contest 10 hdu 5412 CRB and Queries
CRB and Queries Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- HDU 5412 CRB and Queries 动态整体二分
Problem Description There are N boys in CodeLand.Boy i has his coding skill Ai.CRB wants to know who ...
- HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5412 Problem Description There are N boys in CodeLan ...
- 整体二分 HDU - 5808
题目大意 有n个物品,排成一个序列,每个物品有一个di表示取到i要走的距离,vi表示i的价值. 给m组询问[l,r] ,c,sum,问由[l,r]的di<=c的物品能否凑出sum的价值(每个物品 ...
随机推荐
- MySQL数据库(3)_MySQL数据库表记录操作语句
附: MYSQL5.7版本sql_mode=only_full_group_by问题 .查询当前sql_mode: select @@sql_mode .查询出来的值为: set @@sql_mode ...
- LeetCode:罗马数字转整数【13】
LeetCode:罗马数字转整数[13] 题目描述 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 10 ...
- loadrunder之脚本篇——接口传参为本地文件
导言 前几天需要对公司一个专门很重要的接口进行压测,这个还不是重点,重点是传参为本地的图片!刚刚开始通过web_custom_request()函数来解决,可是脚本并不能通过!后面又百度不到答案,通过 ...
- 解决 flex align-items:center 无法居中(微信小程序)
因为最近再做小程序,需要用到flex布局,因为写惯了web项目,初次学习确实感弹性布局的强大(关键是不用再管可恶的ie了). 但是也遇到了align-items:center无法居中的问题,想了很久终 ...
- css的继承性理解
1) 所有的text 相关属性都被继承: 如 font-family font-size; font-style;font-weight;font;font-variant;letter-spacin ...
- 【HackerRank】Bus Station
有n组好朋友在公交车站前排队.第i组有ai个人.还有一辆公交车在路线上行驶.公交车的容量大小为x,即它可以同时运载x个人. 当车站来车时(车总是空载过来),一些组从会队头开始走向公交车. 当然,同一组 ...
- 原生javasxript获取浏览器的滚动距离和可视窗口的高度
原生javasxript获取浏览器的滚动距离和可视窗口的高度 //封装兼容性方法获取滚动的距离 function getScrollOffset(){ if(window.pageXOffset){ ...
- R中的数据重塑函数
1.去除重复数据 函数:duplicated(x, incomparables = FALSE, MARGIN = 1,fromLast = FALSE, ...),返回一个布尔值向量,重复数据的第一 ...
- php数组函数-array_key_exists()
array_key_exists()函数判断某个数组中是否存在指定的key,如果key存 在,则返回true,否则返回flase array_key_exists(key,array); key:必需 ...
- 【转载】有向图强连通分量的Tarjan算法
转载地址:https://www.byvoid.com/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly conn ...