【BZOJ 3110】 [Zjoi2013]K大数查询(整体二分)
【题目】
Description
有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。Input
第一行N,M
接下来M行,每行形如1 a b c或2 a b cOutput
输出每个询问的结果
Sample Input
2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3Sample Output
1
2
1HINT
【样例说明】
第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1
的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是
1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3
大的数是 1 。
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
2操作中c<=Maxlongint
用solve(l,r,S)表示现在处理S集合,S集合是操作集合按照时间排序,所有插入操作满足插入的球数值在l~r,所有询问操作满足其答案在区间l~r。
每个询问操作需要保存一个cnt代表目前在其询问的对应区间内>r的有多少个。
然后我们按顺序扫描操作。先记mid=(l+r)/2
对于插入操作,如果其插入的球数值>mid那么我们将对应区间加1(用线段树维护区间内mid+1~r的球个数)。然后根据其数值让其进入l~mid或mid+1~r。
对于询问操作,我们得到其区间内数值为mid+1~r的个数j,然后如果j+cnt<=k-1那么显然mid不可能是该询问的答案,将该询问进入l~mid并更新其的cnt否则进入mid+1~r。
然后做到l=r的时候就可以解决所有进入此区间的询问。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define INF 0xfffffff
#define Maxn 50010
#define LL long long struct work
{
LL l,r,c,p,ans;
}t[Maxn]; LL a[Maxn],a1[Maxn],a2[Maxn],ans[Maxn];
LL n,m; LL c1[Maxn],c2[Maxn];
void add(LL l,LL r,LL c)
{
// printf("add %d %d %d\n",l,r,c);
for(LL i=l;i<=n;i+=i&(-i))
c1[i]+=c,c2[i]+=l*c;
r++;
for(LL i=r;i<=n;i+=i&(-i))
c1[i]-=c,c2[i]-=r*c;
} LL query(LL l,LL r)
{
// printf("ask %d %d ",l,r);
LL ans=;
for(LL i=r;i>=;i-=i&(-i))
ans+=c1[i]*(r+)-c2[i];
l--;
for(LL i=l;i>=;i-=i&(-i))
ans-=c1[i]*(l+)-c2[i];
// printf("%d\n",ans);
return ans;
} void solve(LL x,LL y,LL l,LL r)
{
if(l==r)
{
for(LL i=x;i<=y;i++) if(t[a[i]].p==) t[a[i]].ans=l;
return;
}
LL mid=(l+r)>>;
a1[]=;a2[]=;
for(LL i=x;i<=y;i++)
{
if(t[a[i]].p==)
{
if(t[a[i]].c<=mid) a1[++a1[]]=a[i];
else a2[++a2[]]=a[i],add(t[a[i]].l,t[a[i]].r,);
}
else
{
LL now=query(t[a[i]].l,t[a[i]].r);
if(now>=t[a[i]].c) a2[++a2[]]=a[i];
else a1[++a1[]]=a[i],t[a[i]].c-=now;
}
}
for(LL i=x;i<=y;i++) if(t[a[i]].p==&&t[a[i]].c>mid) add(t[a[i]].l,t[a[i]].r,-);
LL ll=a1[],rr=a2[];
for(LL i=;i<=ll;i++) a[x+i-]=a1[i];
for(LL i=;i<=rr;i++) a[x+ll+i-]=a2[i];
solve(x,x+ll-,l,mid);
solve(x+ll,x+ll+rr-,mid+,r);
} void init()
{
scanf("%lld%lld",&n,&m);
for(LL i=;i<=m;i++)
{
scanf("%lld%lld%lld%lld",&t[i].p,&t[i].l,&t[i].r,&t[i].c);
}
memset(c1,,sizeof(c1));
memset(c2,,sizeof(c2));
for(LL i=;i<=m;i++) a[i]=i;
solve(,m,,n);
} int main()
{
init();
for(LL i=;i<=m;i++) if(t[i].p==) printf("%lld\n",t[i].ans);
return ;
}
2016-11-09 13:46:58
【BZOJ 3110】 [Zjoi2013]K大数查询(整体二分)的更多相关文章
- BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)
题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...
- BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]
有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...
- BZOJ 3110 [Zjoi2013]K大数查询 ——整体二分
[题目分析] 整体二分显而易见. 自己YY了一下用树状数组区间修改,区间查询的操作. 又因为一个字母调了一下午. 貌似树状数组并不需要清空,可以用一个指针来维护,可以少一个log 懒得写了. [代码] ...
- BZOJ 3110 [ZJOI2013]K大数查询 (整体二分+线段树)
和dynamic rankings这道题的思想一样 只不过是把树状数组换成线段树区间修改,求第$K$大的而不是第$K$小的 这道题还有负数,需要离散 #include <vector> # ...
- BZOJ 3110 [Zjoi2013]K大数查询(整体二分)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 11654 Solved: 3505[Submit][St ...
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ...
- 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 & 3236 [Ahoi2013] 作业 题解
[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 978 Solved: 476 Descri ...
- BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )
BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 418 Solved: 235 [ Submit][ ...
随机推荐
- 提升资源利用率的MapReduce框架
Hadoop系统提供了MapReduce计算框架的开源实现,像Yahoo!.Facebook.淘宝.中移动.百度.腾讯等公司都在借助 Hadoop进行海量数据处理.Hadoop系统性能不仅取决于任务调 ...
- 组合模式(Composite Pattern)
组合模式定义:组合模式允许你将对象组合成树形结构来表现"整体/局部"层次结构,组合能让客户以一致的方式处理个别对象以及对象组合. 当涉及到如:菜单,子菜单之类的问题时,会自然而然的 ...
- C++学习(二)
九.3.内联1)编译器用函数的二进制代码替换函数调用语句,减少函数调用的时间开销.这种优化策略成为内联.2)频繁调用的简单函数适合内联,而稀少调用的复杂函数不适合内联.3)递归函数无法内联.4)通过i ...
- Browser 对象
Browser 对象 window对象表示浏览器中打开的窗口如果文档包含框架(iframe 或 iframe标签),浏览器会为HTML文档创建一个window对象,并为每个框架创建一个额外的windo ...
- 整理SVN代码-->正式环境的代码
最近我被分配到了合并正式补丁代码的工作.聊聊整个流程 第一步解压补丁
- C#类和成员定义
1 定义类 C#用关键字class来定义类.默认情况下,类声明为内部(internal)的,即只有当前项目中的代码才能访问它.与之相对应的,还可以用public关键字来修饰,这样该类还可以由其 ...
- CSS控制长文本内容显示(截取的地方用省略号代替)
自动换行问题,正常字符的换行是比较合理的,而连续的数字和英文字符常常将容器撑大,下面介绍的是CSS如何实现处理的方法. 现实中经常出现一些内容比较长的文本,为了使整体布局美观,需要将文本内容控制在一行 ...
- CustomEditor的文件要放在Assets/Editor目录下
using UnityEditor; using UnityEngine; [CustomEditor(typeof(test))] public class testEditor : Editor ...
- OpenGL中的深度、深度缓存、深度测试及保存成图片
1.深度 所谓深度,就是在openGL坐标系中,像素点Z坐标距离摄像机的距离.摄像机可能放在坐标系的任何位置,那么,就不能简单的说Z数值越大或越小,就是越靠近摄像机. 2.深度缓冲区 深度缓冲区原理就 ...
- struts2初印象
第一次写这么正式的文章,如果写的不好的地方,请指出. 今天玩了一下struts2,不过貌似是我被他玩了.简要笔记如下: 一.配置struts2(在eclipse Helios版本下) (1)先创建一个 ...