P3332 [ZJOI2013]K大数查询
注意操作 $1$ 是在区间的每个位置加入一个数,不是加上一个值
相当于每个位置维护的是一个集合
显然树套树
一开始想的是区间线段树套权值线段树
发现这样询问区间第 $K$ 大时就要先二分答案再用 $O(log^2_n)$ 时间查询
那么单次询问的复杂度就有 $O(log^3_n)$ ,显然不行
考虑权值线段树套区间线段树
单次插入复杂度还是 $O(log^2_n)$,询问时只要在权值线段树上二分就行
那么单次操作复杂度就是 $O(log^2_n)$
据说此题很卡常,为了防止我的大常数导致 $GG$ 所以学了一下线段树的标记用久化
简单说就是标记不下传,只要询问时把经过节点的标记加进来一起计算贡献,代码不难想
因为空间问题所以内层的区间线段树要动态开点
因为插入的数可能为负,所以要离散化,注意 $long long$ !
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
inline ll readll()
{
ll x=; int f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e5+,M=2e7+;
int n,m,cnt,A[N],T;
int rt[N],L[M],R[M],tag[M];//区间线段树的数组,根节点,左儿子,右儿子,永久标记
ll sum[M];//区间线段树数组,区间和
int ql,qr; ll res;
void add(int &o,int l,int r)//区间加1
{
if(!o) o=++cnt;//动态开点
sum[o]+= max( min(r,qr)-max(l,ql)+ ,) ;//因为永久标记所以要这样更新sum
if(l>=ql&&r<=qr) { tag[o]++; return; }//注意我的tag是给儿子的,要先更新sum
int mid=l+r>>;
if(ql<=mid) add(L[o],l,mid);
if(qr>mid) add(R[o],mid+,r);
}
void query(int o,int l,int r,int tot)//区间求和,tot维护当前经过节点的tag的和
{
if(l>=ql&&r<=qr) { res+=sum[o]+1ll*(r-l+)*tot; return; }//更新res
int mid=l+r>>;
if(ql<=mid) query(L[o],l,mid,tot+tag[o]);
if(qr>mid) query(R[o],mid+,r,tot+tag[o]);
}
int POS,RES; ll K;
void ADD(int o,int l,int r)//权值线段树插入
{
add(rt[o],,n); if(l==r) return;
int mid=l+r>>;
if(POS<=mid) ADD(o<<,l,mid);
else ADD(o<<|,mid+,r);
}
void QUERY(int o,int l,int r)//权值线段树处理询问
{
if(l==r) { RES=A[l]; return; }
int mid=l+r>>;
res=; query(rt[o<<|],,n,);//注意优先走大的!
if(res<K) { K-=res; QUERY(o<<,l,mid); }
else QUERY(o<<|,mid+,r);
}
int op[N],dl[N],dr[N],dk[N];//读入的数据
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
n=read(),m=read();
for(int i=;i<=m;i++)
{
op[i]=read(),dl[i]=read(),dr[i]=read(),dk[i]=readll();
if(op[i]==) A[++T]=dk[i];
}
sort(A+,A+T+);
T=unique(A+,A+T+)-A-;//离散化
for(int i=;i<=m;i++)
if(op[i]==) dk[i]=lower_bound(A+,A+T+,dk[i])-A;
for(int i=;i<=m;i++)
{
ql=dl[i],qr=dr[i];
if(op[i]==) { POS=dk[i]; ADD(,,T); }
else
{
K=dk[i]; QUERY(,,T);
printf("%d\n",RES);
}
}
return ;
}
P3332 [ZJOI2013]K大数查询的更多相关文章
- P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)
P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ...
- 洛谷 P3332 [ZJOI2013]K大数查询 解题报告
P3332 [ZJOI2013]K大数查询 题目描述 有\(N\)个位置,\(M\)个操作.操作有两种,每次操作如果是\(\tt{1\ a\ b\ c}\)的形式表示在第\(a\)个位置到第\(b\) ...
- 洛谷 P3332 [ZJOI2013]K大数查询 (整体二分理解)
链接: P3332 题意: 维护 \(n(1\leq n\leq 5\times10^4)\) 个可重整数集,编号从 \(1\) 到 \(n\).有 \(m(1\leq m\leq5\times10^ ...
- P3332 [ZJOI2013]K大数查询 整体二分
终于入门整体二分了,勉勉强强算是搞懂了一个题目吧. 整体二分很多时候可以比较好的离线处理区间\(K\)大值的相关问题.考虑算法流程: 操作队列\(arr\),其中有询问和修改两类操作. 每次在答案的可 ...
- [洛谷P3332][ZJOI2013]K大数查询
题目大意:有$n$个位置,$m$个操作.操作有两种: $1\;l\;r\;x:$在区间$[l,r]$每个位置加上一个数$x$ $2\;l\;r\;k:$询问$[l,r]$中第$k$大的数是多少. 题解 ...
- 洛谷P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树_标记永久化
Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...
- 洛谷 P3332 [ZJOI2013]K大数查询 || bzoj3110
用树套树就很麻烦,用整体二分就成了裸题.... 错误: 1.尝试线段树套平衡树,码农,而且n*log^3(n)慢慢卡反正我觉得卡不过去 2.线段树pushdown写错...加法tag对于区间和的更新应 ...
- 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 ...
随机推荐
- Hyperledger项目中使用的工具
Hyperledger作为一个众多IT厂商参与的项目,全球化的开源社区,其项目的组织形式.流程.工具,都值得借鉴.好工匠离不开好工具,我注意到Hyperledger项目中使用了大量的好工具,包括项目管 ...
- python,itertools模块
itertools模块的使用: # coding=utf-8 """ itertools模块 """ import itertools im ...
- CSS 中的 px、em、rem 和 vh
区分 px:Pixel.像素. em:相对长度单位.继承父级元素的 font-size,值是相对于父级元素font-size的倍数. rem:Root em.相对于根元素(即 <html> ...
- Java 5新特性 for each 和Iterator的选择
在使用一边做迭代操作一边做删除数组元素操作是应该使用Iterator package for_each_And_Iterator; public class Commodity { private S ...
- web开发四个作用域
web开发一共有四个作用域,范围从高到低分为appliaction作用域(全局作用域),session作用域,request作用域和page作用域.${base}是el表达式语法,它会自动先从page ...
- PLSQL_Developer 连接win7_64位oracle11g
window7系统 安装的64位 oracle11g,连接32位PLSQL_Developer 1 . 下载 PLSQL_Developer 9.0以上版本(绿色含汉化) 官方的 instantc ...
- angular 响应式表单
- arp欺骗进行流量截获-2
上一篇讲了原理,那么这一篇主要讲如何实现.基本上也就是实现上面的两个步骤,这里基于gopacket实现,我会带着大家一步步详细把每个步骤都讲到. ARP 欺骗 首先就是伪造ARP请求,让A和B把数据包 ...
- strcmp返回值布尔类型的判断
strcmp: 用于比较两个字符串,原型如下: int strcmp ( char const *s1, char const *s2):如果s1小于s2,strcmp函数返回一个小于零的值.如果s1 ...
- cinder侧卸载卷流程分析
cinder侧卸载卷分析,存储类型以lvm+iscsi的方式为分析基础在虚机卸载卷的过程中,主要涉及如下三个函数1)cinder.volume.api.begin_detaching 把volume的 ...