BZOJ 3110 [Zjoi2013]K大数查询(整体二分)
3110: [Zjoi2013]K大数查询
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 11654 Solved: 3505
[Submit][Status][Discuss]
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 c
Output
输出每个询问的结果
Sample Input
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
Sample Output
2
1
HINT
【样例说明】
第一个操作 后位置 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
题解
求第K大。
然后我们把权值设为n-c+1;
最后答案为n-ans+1就把问题转化为了第k小
不过这题是插入。其实不是很难毕竟只是把权值小于mid的数的位置都加一就行了,我们把修改二分和一个位置多少个权值没有关系。
和以前唯一的区别就是这次是整体修改,用线段树就行了(就是慢)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const long long N=;
struct query{
long long type,x,y,w,id;
}q[N],c2[N],c1[N];
long long ans[N],m,n,tot;
struct tree{
long long l,r,lazy,sum;
}tr[N*];
void update(long long now){
tr[now].sum=tr[now*].sum+tr[now*+].sum;
}
void pushdown(long long now){
if(tr[now].lazy==)return;
tr[now*].sum+=(tr[now*].r-tr[now*].l+)*tr[now].lazy;
tr[now*+].sum+=(tr[now*+].r-tr[now*+].l+)*tr[now].lazy;
tr[now*].lazy+=tr[now].lazy;
tr[now*+].lazy+=tr[now].lazy;
tr[now].lazy=;
}
void build(long long l,long long r,long long now){
tr[now].l=l;tr[now].r=r;
if(l==r)return;
long long mid=(l+r)>>;
build(l,mid,now*);
build(mid+,r,now*+);
}
void add(long long l,long long r,long long c,long long now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
tr[now].sum+=(tr[now].r-tr[now].l+)*c;
tr[now].lazy+=c;
return;
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid)add(l,r,c,now*+);
else if(r<=mid)add(l,r,c,now*);
else{
add(l,mid,c,now*);
add(mid+,r,c,now*+);
}
update(now);
}
long long check(long long l,long long r,long long now){
pushdown(now);
if(tr[now].l==l&&tr[now].r==r){
return tr[now].sum;
}
long long mid=(tr[now].l+tr[now].r)>>;
if(l>mid)return check(l,r,now*+);
else if(r<=mid)return check(l,r,now*);
else return check(l,mid,now*)+check(mid+,r,now*+);
}
void solve(long long l,long long r,long long L,long long R){
if(l>r)return ;
if(L==R){
for(long long i=l;i<=r;i++){
if(q[i].type==)ans[q[i].id]=L;
}
return;
}
long long mid=(L+R)>>;
long long lnow=;long long rnow=;
for(long long i=l;i<=r;i++){
if(q[i].type==){
if(q[i].w<=mid){
add(q[i].x,q[i].y,,);
c1[++lnow]=q[i];
}
else c2[++rnow]=q[i];
}
else{
long long tmp=check(q[i].x,q[i].y,);
if(tmp>=q[i].w)c1[++lnow]=q[i];
else{
q[i].w-=tmp;
c2[++rnow]=q[i];
}
}
}
for(long long i=;i<=lnow;i++){
if(c1[i].type==)add(c1[i].x,c1[i].y,-,);
}
for(long long i=;i<=lnow;i++){
q[l+i-]=c1[i];
}
for(long long 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("%lld%lld",&n,&m);
build(,n,);
for(long long i=;i<=m;i++){
long long k,a,b,c;
scanf("%lld%lld%lld%lld",&k,&a,&b,&c);
if(k==){
q[i].type=;q[i].x=a;q[i].y=b;q[i].w=n-c+;
}
else{
q[i].type=;q[i].x=a;q[i].y=b;q[i].w=c;q[i].id=++tot;
}
}
solve(,m,-n,n);
for(long long i=;i<=tot;i++){
printf("%lld\n",n-ans[i]+);
}
return ;
}
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: 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][ ...
随机推荐
- SpringCloud学习笔记(7)----Spring Cloud Netflix之负载均衡-Ribbon的深入理解
1. 注解@LoadBalanced 作用:识别应用名称,并进行负载均衡. 2. 入口类:LoadBalancerAutoConfiguration 说明:类头上的注解可以知道Ribbon 实现的负载 ...
- ZBrush中Zproject与SubTool的综合应用
在ZBrush中有很多工具也需要配合子物体工具来使用,如笔刷中的Zproject(投射笔刷)就需要子物体工具来配合使用,本文将讲解一下它的用法. 1. 首先创建一个平面,在Tool(工具)面板中选择P ...
- confluence6.0.3安装文档
一.Atlassian Confluence 6.0.3安装文档包含内容 1.wiki的安装步骤: 2.旧系统迁移中碰到的无法编辑和问题和解决方案: 3.wiki源码安装包.连接mysql用的jar包 ...
- Spark脚本调用
Spark提供了多个脚本来作为程序的入口,其中最常用的是交互脚本 spark-shell, pyspark,还有spark sql的客户端spark-sql. 这些脚本最后都会归结到对SparkSub ...
- js验证输入框
项目开发中,都会有对表单form中的input输入框进行一些限制验证 如: <!DOCTYPE html><html lang="en"> <head ...
- springboot --> web 应用开发-CORS 支持
一.Web 开发经常会遇到跨域问题,解决方案有:jsonp,iframe,CORS 等等 CORS 与 JSONP 相比 1. JSONP 只能实现 GET 请求,而 CORS 支持所有类型的 HTT ...
- sqlmap 实战漏洞平台dvwa进行密码破解
2016-05-24 (1)实验的具体的环境极其思路 首先我们要检测我们的漏洞平台是否有sql注入 ,进行简单的测试发现在用户userid 上存在注入的漏洞 使用抓包工具对其cookie 进行获取如下 ...
- JDBC读写MySQL的大字段数据
JDBC读写MySQL的大字段数据 不管你是新手还是老手,大字段数据的操作常常令你感到很头痛.因为大字段有些特殊,不同数据库处理的方式不一样,大字段的操作常常是以流的方式 来处理的.而非一般的字段 ...
- PHP中比较有用的几个函数
php_check_syntax 这个函数可以用来检查特定文件中的PHP语法是否正确. highlight_string 当你想要把PHP代码显示到页面上时,highlight_string()函数就 ...
- 通过唯一ID实现简单的日志跟踪实现
在实际项目中,通知我们需要记录一些日志,方便问题核查.但是日志多了就很容易混乱,请求,响应,执行中的日志无法对应,这时就需要为请求进行标记唯一ID来进行跟踪. /** * 记录请求日志 * * Cla ...