3110: [Zjoi2013]K大数查询

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 5881  Solved: 1958
[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

2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3

Sample Output

1
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

整体二分是什么东西? 我们知道 主席树查询是一个类似二分的过程,但是这道题有修改,一次一次修改太慢了,这时就用上二分的思想了。

一个一个二分太慢了,那么我们把一堆东西一起二分,也就是把他们不断地划分,归类。

二分一个lb和ub,比(lb+ub)/2大的归到右边,小的归到左边,然后就完了。

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 500010
typedef long long ll;
struct data
{
ll v;
ll l,r,type,pos;
}op[N];
vector<data> lp,rp;
ll n,m;
ll tag[N*],t[N*],ans[N];
bool flag[N*];
void update(int l,int r,int x,int a,int b,int num)
{
if(l>b||r<a) return;
if(l>=a&&r<=b)
{
tag[x]+=num;
return;
}
t[x]+=(min(r,b)-max(l,a)+)*num;
update(l,(l+r)/,x*,a,b,num);
update((l+r)/+,r,x*+,a,b,num);
}
ll query(int l,int r,int x,int a,int b)
{
if(l>b||r<a) return ;
if(l>=a&&r<=b) return t[x]+(r-l+)*tag[x];
ll ret=;
ret+=(min(r,b)-max(l,a)+)*tag[x];
ret+=query(l,(l+r)/,x*,a,b);
ret+=query((l+r)/+,r,x*+,a,b);
return ret;
}
void solve(int l,int r,int lb,int ub)
{
// printf("((((((((((((((((((((((\n");
// printf("lb=%d ub=%d\n",lb,ub);
// printf("left=%d right=%d\n",l,r);
if (l > r) return ;
if(lb==ub)
{
for(int i=l;i<=r;i++)
if(op[i].type==)
{
flag[op[i].pos]=true;
ans[op[i].pos]=lb;
}
return;
}
ll mb=lb+(ub-lb)/;
lp.clear(); rp.clear();
for(int i=l;i<=r;i++)
{
if(op[i].type==)
{
if(op[i].v>mb)
{
// printf("------------\n");
// printf("l=%d r=%d\n",op[i].l,op[i].r);
update(,n,,op[i].l,op[i].r,);
// printf("------------\n");
rp.push_back(op[i]);
}
else
lp.push_back(op[i]);
}
else
{
ll c=query(,n,,op[i].l,op[i].r);
// printf("op[i].l=%d op[i].r=%d\n",op[i].l,op[i].r);
// printf("c=%d\n",c);
if(c>=op[i].v)
{
rp.push_back(op[i]);
}
else
{
op[i].v-=c;
lp.push_back(op[i]);
}
}
} for(int i=l;i<=r;i++)
{
if(op[i].type==&&op[i].v>mb)
update(,n,,op[i].l,op[i].r,-);
} ll mid=l+lp.size();
for(int i=;i<lp.size();i++)
{
op[i+l]=lp[i];
}
for(int i=;i<rp.size();i++)
{
op[mid+i]=rp[i];
}
// printf(")))))))))))))))))))))\n");
solve(l,mid-,lb,mb);
solve(mid,r,mb+,ub);
}
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%lld%lld%lld%lld",&op[i].type,&op[i].l,&op[i].r,&op[i].v);
op[i].pos=i;
}
solve(,m,-n,n);
for(int i=;i<=m;i++)
{
if(flag[i]) printf("%lld\n",ans[i]);
}
return ;
}

bzoj3110的更多相关文章

  1. 【bzoj3110】 Zjoi2013—K大数查询

    http://www.lydsy.com/JudgeOnline/problem.php?id=3110 (题目链接) 题意 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在 ...

  2. 【BZOJ3110】K大数查询(整体二分)

    [BZOJ3110]K大数查询(整体二分) 题面 BZOJ 题解 看了很久整体二分 一直不知道哪里写错了 ... 又把树状数组当成线段树区间加法来用了.. 整体二分还是要想清楚在干什么: 我们考虑第\ ...

  3. BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...

  4. 【BZOJ3110】【LG3332】[ZJOI2013]K大数查询

    [BZOJ3110][LG3332][ZJOI2013]K大数查询 题面 洛谷 BZOJ 题解 和普通的整体分治差不多 用线段树维护一下每个查询区间内大于每次二分的值\(mid\)的值即可 然后再按套 ...

  5. 【BZOJ3110】[Zjoi2013]K大数查询 树套树

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

  6. 【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)

    题意:有N个位置,M个操作.操作有两种,每次操作 如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...

  7. 【BZOJ3110】[ZJOI2013]K大数查询(整体二分)

    题目: BZOJ3110 分析: 整体二分模板题-- 先明确一下题意:每个位置可以存放多个数,第一种操作是"加入 (insert) "一个数而不是"加上 (add) &q ...

  8. bzoj3110树套树

    wa一片,最后一个T,终于心碎了... 为什么没人告诉我要开longlong 为什么所有人都说没有负数 #include<cstdio> #include<algorithm> ...

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

    喜闻乐见的简单树套树= =第一维按权值建树状数组,第二维按下标建动态开点线段树,修改相当于第二维区间加,查询在树状数组上二分,比一般的线段树还短= =可惜并不能跑过整体二分= =另外bzoj上的数据有 ...

随机推荐

  1. UITableViewHeaderFooterView的封装

    UITableViewHeaderFooterView的封装 特点 1. 封装的 UITableViewHeaderFooterView 能够让用户更好的自定义自己的 headerView; 2. 封 ...

  2. Objective-C 30分钟入门教程

    Objective-C 30分钟入门教程 我第一次看OC觉得这个语言的语法有些怪异,为什么充满了@符号,[]符号,函数调用没有()这个,但是面向对象的高级语言也不外乎类,接口,多态,封装,继承等概念. ...

  3. (一)Maven初步了解与认识

    Apache Maven是一个软件项目管理的综合工具.基于项目对象模型(POM)的概念,提供了帮助管理构建.文档.报告.依赖.发布等方法,Maven简化和标准化项目建设过程.处理编译,分配,文档,团队 ...

  4. 转载:WinForm中播放声音的三种方法

    转载:WinForm中播放声音的三种方法 金刚 winForm 播放声音 本文是转载的文章.原文出处:http://blog.csdn.net/jijunwu/article/details/4753 ...

  5. 敏捷遇上UML—软创基地马年大会(广州站 2014-4-19)

        我们将在广州为您奉献高端知识大餐,当敏捷遇上UML,会发生怎样的化学作用呢?首席专家张老师将会为您分享需求分析及软件设计方面的最佳实践,帮助您掌握敏捷.UML及两者相结合的实战技巧. 时间:2 ...

  6. Oracle 11g数据库详细安装步骤图解

    1.先到Oracle官网上下载11g oracle Database 11g 第 2 版 (11.2.0.1.0) 标准版.标准版 1 以及企业版 适用于 Microsoft Windows (x64 ...

  7. Redhat Linux安装JDK 1.7

    本篇主要介绍在Redhat Linux(Red Hat Enterprise Linux Server release 5.7 (Tikanga))系统上安装JDK 1.7,其它Linux平台安装也大 ...

  8. SQL SERVER 2008:内部查询处理器错误: 查询处理器在执行过程中遇到意外错误

       今天一个同事突然告诉我,以前跑得很正常的一个SQL语句,执行时突然报如下错误:         消息1222,级别16,状态18,第1 行         已超过了锁请求超时时段.        ...

  9. ARMGNU伪指令

    符号定义伪指令 .global,.local,.set,.equ .global 使得符号对连接器可见,变为对整个工程可用的全局变量 .global symbol .local 表示符号对外部不可见, ...

  10. 理解 Node.js 里的 process.nextTick()

    有很多人对Node.js里process.nextTick()的用法感到不理解,下面我们就来看一下process.nextTick()到底是什么,该如何使用. Node.js是单线程的,除了系统IO之 ...