题目描述

有N个位置,M个操作。操作有两种,每次操作如果是:

  • 1 a b c:表示在第a个位置到第b个位置,每个位置加上一个数c
  • 2 a b c:表示询问从第a个位置到第b个位置,第C大的数是多少。

思路

  比较基础的整体二分。我们二分出$mid,对于值域[l,r]对应的操作[L,R]$,若为操作1,则考虑把$val>mid$的插入线段树中,表示比$mid$大的值的个数,若为操作2,先询问$[q[i].l,q[i].r]$中比$mid$大的值的个数,然后把当前询问填到左右区间再处理。讲的很简单,调过来整体二分原理的一些东西,,,毕竟这题还是比较板子的。

code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define I inline
#define smid (l+r>>1)
#define lch (now<<1)
#define rch (now<<1|1)
using namespace std;
const int N=;
typedef long long LL;
int n,m,tot;
LL ans[N];
struct segment
{
LL sum,pls;
}sgt[N<<];
struct node
{
int l,r,k,op,id;
}q[N<<],q1[N<<],q2[N<<]; I int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} I LL readll()
{
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} I void pushup(int now)
{
sgt[now].sum=sgt[lch].sum+sgt[rch].sum;
} I void pushdown(int now,int l,int r)
{
if(!sgt[now].pls)return;
sgt[lch].pls+=sgt[now].pls;
sgt[rch].pls+=sgt[now].pls;
sgt[lch].sum+=(smid-l+)*sgt[now].pls;
sgt[rch].sum+=(r-smid)*sgt[now].pls;
sgt[now].pls=;
} I void modify(int now,int l,int r,int x,int y,int val)
{
if(x<=l&&r<=y)
{
sgt[now].pls+=val;
sgt[now].sum+=(r-l+)*val;
return;
}
pushdown(now,l,r);
if(x<=smid)modify(lch,l,smid,x,y,val);
if(smid<y)modify(rch,smid+,r,x,y,val);
pushup(now);
} I LL query(int now,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return sgt[now].sum;
pushdown(now,l,r);
LL res=;
if(x<=smid)res+=query(lch,l,smid,x,y);
if(smid<y)res+=query(rch,smid+,r,x,y);
pushup(now);
return res;
} I 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(q[i].op==)ans[q[i].id]=l;
return;
}
int mid=(l+r>>),cnt1=,cnt2=;
for(int i=L;i<=R;i++)
{
if(q[i].op==)
{
if(q[i].k>mid)
modify(,,n,q[i].l,q[i].r,),q2[++cnt2]=q[i];
else q1[++cnt1]=q[i];
}
else
{
LL tmp=query(,,n,q[i].l,q[i].r);
if(q[i].k>tmp)q[i].k-=tmp,q1[++cnt1]=q[i];
else q2[++cnt2]=q[i];
}
}
for(int i=;i<=cnt2;i++)if(q2[i].op==)modify(,,n,q2[i].l,q2[i].r,-);
for(int i=;i<=cnt1;i++)q[L+i-]=q1[i];
for(int i=;i<=cnt2;i++)q[L+cnt1+i-]=q2[i];
solve(l,mid,L,L+cnt1-);solve(mid+,r,L+cnt1,R);
} int main()
{
n=read();m=read();
for(int i=;i<=m;i++)
{
q[i].op=read();q[i].l=read();q[i].r=read();q[i].k=readll();
if(q[i].op==)q[i].id=++tot;
}
solve(-n,n,,m);
for(int i=;i<=tot;i++)printf("%lld\n",ans[i]);
}

[ZJOI2013]K大数查询——整体二分的更多相关文章

  1. P3332 [ZJOI2013]K大数查询 整体二分

    终于入门整体二分了,勉勉强强算是搞懂了一个题目吧. 整体二分很多时候可以比较好的离线处理区间\(K\)大值的相关问题.考虑算法流程: 操作队列\(arr\),其中有询问和修改两类操作. 每次在答案的可 ...

  2. BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]

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

  3. BZOJ3110:[ZJOI2013]K大数查询(整体二分)

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

  4. BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)

    题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...

  5. BZOJ 3110 [Zjoi2013]K大数查询 ——整体二分

    [题目分析] 整体二分显而易见. 自己YY了一下用树状数组区间修改,区间查询的操作. 又因为一个字母调了一下午. 貌似树状数组并不需要清空,可以用一个指针来维护,可以少一个log 懒得写了. [代码] ...

  6. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

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

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

    浅谈离线分治算法:https://www.cnblogs.com/AKMer/p/10415556.html 题目传送门:https://lydsy.com/JudgeOnline/problem.p ...

  8. BZOJ 3110 [ZJOI2013]K大数查询 (整体二分+线段树)

    和dynamic rankings这道题的思想一样 只不过是把树状数组换成线段树区间修改,求第$K$大的而不是第$K$小的 这道题还有负数,需要离散 #include <vector> # ...

  9. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

随机推荐

  1. 计算机视觉(二)-opencv之createTrackbar()详解

    摘要: 我学习openCV3看的是<学习openCV3>这本书,很厚的一本,不知道是不是因为自己看的还不是很多,个人觉得里面的有些重要函数讲的不是很详细,比如createTrackbar( ...

  2. selenium+testNG自动化测试框架搭建

    自动化测试框架搭建 1 Java环境的搭建 1.1访问oracle的官网下载最新版本的jdk http://www.oracle.com/technetwork/java/javase/downloa ...

  3. 从0开始学FreeRTOS-(列表&列表项)-6

    # FreeRTOS列表&列表项的源码解读 第一次看列表与列表项的时候,感觉很像是链表,虽然我自己的链表也不太会,但是就是感觉很像. 在FreeRTOS中,列表与列表项使用得非常多,是Free ...

  4. java生成32位UUID

    java生成32位UUID,具体代码如下: package com.fxsen.uuid; import java.util.UUID; /** * Copyright: Copyright (c) ...

  5. Arouter核心思路和源码详解

    前言 阅读本文之前,建议读者: 对Arouter的使用有一定的了解. 对Apt技术有所了解. Arouter是一款Alibaba出品的优秀的路由框架,本文不对其进行全面的分析,只对其最重要的功能进行源 ...

  6. mysqlbinlog增量恢复(基于使用事件位置position的恢复)

    1.在xtrabackup 备份+还原文章中我们记录了备份到的binlog文件名和position点位置使用如下命令就可以进行增量的恢复了shell> mysqlbinlog --stop-po ...

  7. conversion function——转换函数

    类型转换函数 与 explicit关键字 1.类型转换函数 在C++中,可以使用构造函数将一个指定类型的数据转换为类的对象,也可以使用类型转换函数 (type conversion function) ...

  8. Python3数据分析与挖掘建模实战 ☝☝☝

    Python3数据分析与挖掘建模实战 Python数据分析简介 Python入门 运行:cmd下"python hello.py" 基本命令: 第三方库 安装 Windows中 p ...

  9. 手把手教你吧Python应用到实际开发 不再空谈悟法☝☝☝

    手把手教你吧Python应用到实际开发 不再空谈悟法☝☝☝ 想用python做机器学习吗,是不是在为从哪开始挠头?这里我假定你是新手,这篇文章里咱们一起用Python完成第一个机器学习项目.我会手把手 ...

  10. JDBC-第1篇-基础

    话不多说,直接开撸代码. 1.首先自己的环境使用的是maven项目+idea工具+mysql8.0.18 (使用maven项目的好处就是方便,不用手动导入相关的驱动包,在pom.xml配置即可) 2. ...