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 ...
随机推荐
- Luogu 4784 [BalticOI 2016 Day2]城市
斯坦纳树复习,我暑假的时候好像写过[JLOI2015]管道连接来着. 设$f_{i, s}$表示以$i$为根,$k$个重要点的连通状态为$s$,($0$代表没有连进最小生成树里面去,$1$代表连进了最 ...
- keys()
keys():返回一个数组,里面是符合匹配模式的键列表 $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $pattern = ...
- vue.js的生命周期 及其created和mounted的部分
网上很多人有所总结,转载自: https://segmentfault.com/a/1190000008570622 关于created和mounted的部分,也可以参考: https://blo ...
- npm 升级
当我们运行某个项目是 会提示 > my-first-vue-project@1.0.0 dev C:\Users\ASUS\my-project > node build/dev-serv ...
- Tomcat 与 数据库连接池 的小坑
连接池的优点众所周知. 我们可以自己实现数据库连接池,也可引入实现数据库连接池的jar包,按要求进行配置后直接使用. 关于这方面的资料,好多dalao博客上记录的都是旧版本Tomcat的配置方式,很可 ...
- whereis libjpeg.so.7
在服务器上调用import ImageFont时报如下错误 ImportError: The _imagingft C module is not installed (服务器为Centos5.5, ...
- HBuilder生成代码行快捷键
1.在body内输入div.abc按下tab键 效果:<div class="abc"></div> 2.在body内输入div#abc按下tab键 效果: ...
- [web] [vscode] 自定义语言缩进
vscode 默认的html 语言的缩进有点过,貌似一个tab6个space, html看起来太空了,所幸的是可以自己调整单个语言的缩进模式. 方法如下 Preferences: Open User ...
- sqlserver中 多条数据合并成一条数据 (stuff 与 for xml path 连用)
SQL 列转行,即多行合并成一条 需求:按照分组,将多条记录内容合并成一条,效果如下: 数据库示例: CREATE TABLE [t2]([NID] [bigint] NULL,[district ...
- Kotlin if else判断
Kotlin的if相对与java,有着较为灵活的用法. if是用来判断. if在Kotlin里面可以作为表达式来使用. 如果熟悉C java C#等 A>B:A?B这个判断应该是很熟悉,而Kot ...