[ZJOI2013]K大数查询
Description:
给定一个序列,支持两种操作
1.在[L,R]的每个位置上加上一个数 (注意一个位置上有多个数)
2.查询[L,R]上所有数中的第K大
Hint:
\(n,m<=5e4\)
Solution:
一道很好的整体二分题,在值域上二分所有询问的答案,并在线段树上维护\(size\)
详见代码
#include<bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
using namespace std;
typedef long long ll;
const int mxn=5e4+5;
struct Q {
    int opt,l,r,x,id;
}q[mxn],tl[mxn],tr[mxn];
int n,m,tot;
ll ans[mxn],t[mxn<<2],rec[mxn<<2],tag[mxn<<2];
namespace SegmentTree {
    inline void push_up(int p) {
        t[p]=t[ls]+t[rs];
    };
    inline void push_down(int l,int r,int p) {
        if(rec[p]) {
            tag[ls]=tag[rs]=t[ls]=t[rs]=0;
            rec[ls]=rec[rs]=1;
            rec[p]=0;
        }
        if(tag[p]) {
            int mid=(l+r)>>1;
            tag[ls]+=tag[p],tag[rs]+=tag[p];
            t[ls]+=(mid-l+1)*tag[p],
            t[rs]+=(r-mid)*tag[p];
            tag[p]=0;
        }
    };
    void update(int l,int r,int ql,int qr,int val,int p)	{
        if(ql<=l&&r<=qr) {
            t[p]+=(r-l+1)*val;
            tag[p]+=val;
            return ;
        }
        int mid=(l+r)>>1; push_down(l,r,p);
        if(ql<=mid) update(l,mid,ql,qr,val,ls);
        if(qr>mid) update(mid+1,r,ql,qr,val,rs);
        push_up(p);
    };
    ll query(int l,int r,int ql,int qr,int p) {
        if(ql<=l&&r<=qr) return t[p]; ll res=0;
        int mid=(l+r)>>1; push_down(l,r,p);
        if(ql<=mid) res+=query(l,mid,ql,qr,ls);
        if(qr>mid) res+=query(mid+1,r,ql,qr,rs);
        return res;
    };
}
using namespace SegmentTree;
int ss;
void solve(int l,int r,int ql,int qr)
{
    if(l==r) {
        for(int i=ql;i<=qr;++i)
            if(q[i].opt==2)
                if(!ans[q[i].id]) ans[q[i].id]=l;
        return ;
    }
    int mid=(l+r)>>1,fl=0,fr=0;
    int L=0,R=0;rec[1]=1,tag[1]=t[1]=0; //有些变量不能开全局,切记!!!
    for(int i=ql;i<=qr;++i) {
        if(q[i].opt==1) {
            if(q[i].x>mid) {
                update(1,n,q[i].l,q[i].r,1,1);
                tr[++R]=q[i];
            }
            else tl[++L]=q[i];
        }
        else {
            ll tp=query(1,n,q[i].l,q[i].r,1);
            if(q[i].x<=tp) tr[++R]=q[i],fr=1;
            else q[i].x-=tp,tl[++L]=q[i],fl=1;
        }
    }
        for(int i=1;i<=L;++i) q[ql+i-1]=tl[i];
        for(int i=L+1;i<=L+R;++i) q[ql+i-1]=tr[i-L];
        if(fl) solve(l,mid,ql,ql+L-1);
        if(fr) solve(mid+1,r,ql+L,qr);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i) {
        scanf("%d%d%d%d",&q[i].opt,&q[i].l,&q[i].r,&q[i].x);
        if(q[i].opt==2) q[i].id=++tot;
    }
    solve(-n,n,1,m);
    for(int i=1;i<=tot;++i) printf("%lld\n",ans[i]);
    return 0;
}
[ZJOI2013]K大数查询的更多相关文章
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
		3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ... 
- 树套树专题——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大数查询 树状数组套线段树
		3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ... 
- 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][ ... 
- BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组
		BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ... 
- P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)
		P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ... 
- 【BZOJ3110】【LG3332】[ZJOI2013]K大数查询
		[BZOJ3110][LG3332][ZJOI2013]K大数查询 题面 洛谷 BZOJ 题解 和普通的整体分治差不多 用线段树维护一下每个查询区间内大于每次二分的值\(mid\)的值即可 然后再按套 ... 
- 3110: [Zjoi2013]K大数查询
		3110: [Zjoi2013]K大数查询 https://lydsy.com/JudgeOnline/problem.php?id=3110 分析: 整体二分+线段树. 两种操作:区间加入一个数,区 ... 
- 洛谷 P3332 [ZJOI2013]K大数查询 解题报告
		P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ... 
随机推荐
- C程序的内存分配及动态内存
			1.程序内存的分配 一个由C/C++编译的程序占用的内存分为以下几个部分:1)栈区(stack) — 由编译器自动分配释放 , 存放为运行函数而分配的局部变量. 函数参数. 返回数据. 返回地址等. ... 
- The.Glory.of.Innovation 创新之路2科学基石
			犹太民族很早就确立了他们的生存法则:资源.土地,以及一切有形的东西都会消失,一个人最重要的财富是自己的头脑.是知识.是创造. 有些选择是被动的,有些选择是主动的,一旦决心要把技术变成自己的,独立的 ... 
- 利用SVD-推荐未尝过的菜肴2
			推荐未尝过的菜肴-基于SVD的评分估计 实际上数据集要比我们上一篇展示的myMat要稀疏的多. from numpy import linalg as la from numpy import * d ... 
- 函数wait和waitpid
			函数wait 一个进程在终止时会关闭所有文件描述符,释放在用户空间释放的内存,但它的PCB还保留着,内核在其中保存一些信息:如果是正常终止时则保存着退出状态,如果是异常终止则保存着导致该进程终止的信号 ... 
- Android NDK开发调试
			ndk-stack: https://developer.android.com/ndk/guides/ndk-stack?hl=zh-cn JNI开发: https://developer.andr ... 
- 一脸懵逼加从入门到绝望学习hadoop之 org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlException): Permission denied: user=Administrator, access=WRITE, inode="/":root:supergroup:drwxr-xr报错
			1:初学hadoop遇到各种错误,这里贴一下,方便以后脑补吧,报错如下: 主要是在window环境下面搞hadoop,而hadoop部署在linux操作系统上面:出现这个错误是权限的问题,操作hado ... 
- Hadoop的namenode的管理机制,工作机制和datanode的工作原理
			HDFS前言: 1) 设计思想 分而治之:将大文件.大批量文件,分布式存放在大量服务器上,以便于采取分而治之的方式对海量数据进行运算分析: 2)在大数据系统中作用: 为各类分布式运算框架(如:mapr ... 
- 【Maven】Select Dependency 无法检索
			问题: 在 “pom.xml” 中,点击 “Dependencies” -> “Add” 添加依赖时,无法检索. 如下图所示: 解决办法: 依次点击 “Windows”->“Show ... 
- Java基础知识➣网络Socket(六)
			概述 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net 包中提供了两种常见的网络协议的支持: TCP:TCP 是传输控制协议的缩写,它保障了两个应用程序之 ... 
- python排列组合之itertools模块
			1. 参考 几个有用的python函数 (笛卡尔积, 排列, 组合) 9.7. itertools — Functions creating iterators for efficient loopi ... 
