bzoj3110: [Zjoi2013]K大数查询 【树套树,标记永久化】
//==========================
蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/ 转载要声明!
//==========================
好久没写题解了。
但是这题太神了然后做法太神了于是写一下。
这题做法很多,比如黄学长hzw的权值线段树套线段树,比如学长云的bit套主席树(其实是写法更神然后我不会用)。
然后看到hzhwcmhf大神题解。
http://tieba.baidu.com/p/2246783535
震惊了。
好了开说说做法。建一颗朴素的线段树,树的每个点表示每个区间,然后每个区间建两棵树,一棵是mark树,一棵是all树,两棵都是权值线段树。
“mark表示该区间每个点上都会加上mark线段树里的元素
all表示该区间所有点的元素集合”
这道题麻烦的地方就在与标记,如果标记要下传的话,那么每次可能要下传很多个点。
于是标记永久化,就是不要下传。
对于修改:如果修改区间是当前点区间,那么就加入mark中。如果不是,那么就加入all。操作都是单点修改。加入mark时为c+1,加入all是为c+len
对于询问:首先包含在查询区间内的区间的所有的all,然后mark要去掉没有重合在一起的地方,乘回差值。
(太久没写题解都不知道怎么说了)
速度还是挺快的
type
arr=record
all,mark:longint;
end;
const
maxn=;
var
tree:array[..maxn]of arr;
size,lson,rson,root1,root2:array[..maxn]of longint;
tot,sum,n,m,i,j,k,l:longint; function add:longint;
begin
inc(tot);
exit(tot);
end; procedure sinsert(var x:longint;y,z:longint);
var
left,right,mid,old:longint;
begin
if x= then x:=add;
old:=x;
left:=;
right:=n;
while left<=right do begin
mid:=(left+right)>>;
inc(size[x],z);
if left=right then break;
if y<=mid then begin
right:=mid;
if lson[x]= then lson[x]:=add;
x:=lson[x];
end
else begin
left:=mid+;
if rson[x]= then rson[x]:=add;
x:=rson[x];
end;
end;
x:=old;
end; procedure binsert(x,l,r,tl,tr,tc:longint);
var
mid:longint;
begin
if (tl=l) and (tr=r) then begin
sinsert(tree[x].mark,tc,);
exit;
end;
mid:=(l+r)>>;
sinsert(tree[x].all,tc,tr-tl+);
if tl>mid then binsert(x<<+,mid+,r,tl,tr,tc)
else
if tr<=mid then binsert(x<<,l,mid,tl,tr,tc)
else begin
binsert(x<<,l,mid,tl,mid,tc);
binsert(x<<+,mid+,r,mid+,tr,tc);
end;
end; procedure before(x,l,r,tl,tr:longint);
var
mid:longint;
begin
inc(sum);
root1[sum]:=tree[x].mark;
root2[sum]:=tr-tl+;
if (tl=l) and (tr=r) then begin
inc(sum);
root1[sum]:=tree[x].all;
root2[sum]:=;
exit;
end;
mid:=(l+r)>>;
if tl>mid then before(x<<+,mid+,r,tl,tr)
else
if tr<=mid then before(x<<,l,mid,tl,tr)
else begin
before(x<<,l,mid,tl,mid);
before(x<<+,mid+,r,mid+,tr);
end;
end; procedure query(x,y,z:longint);
var
left,right,now,mid:longint;
begin
sum:=;
before(,,n,x,y);
left:=;
right:=n;
while left<right do begin
now:=;
mid:=(left+right)>>;
for i:= to sum do
now:=size[rson[root1[i]]]*root2[i]+now;
if now<z then begin
dec(z,now);
right:=mid;
for i:= to sum do
root1[i]:=lson[root1[i]];
end
else begin
left:=mid+;
for i:= to sum do
root1[i]:=rson[root1[i]];
end;
end;
writeln(left);
end; begin
readln(n,m);
while m> do begin
dec(m);
readln(i,j,k,l);
if i= then binsert(,,n,j,k,l)
else query(j,k,l);
end;
readln;
readln;
end.
数组开小竟然wa了两次。
bzoj3110: [Zjoi2013]K大数查询 【树套树,标记永久化】的更多相关文章
- P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)
P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ...
- BZOJ3110[Zjoi2013]K大数查询(树状数组+整体二分)
3110 [Zjoi2013]K大数查询 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a ...
- BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...
- BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...
- bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】
模板题,折腾了许久. cqd分治整体二分,感觉像是把询问分到答案上. #include <bits/stdc++.h> #define rep(i, a, b) for (int i = ...
- [BZOJ3110] [Zjoi2013] K大数查询 (树套树)
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置 ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- BZOJ3110: [Zjoi2013]K大数查询
喜闻乐见的简单树套树= =第一维按权值建树状数组,第二维按下标建动态开点线段树,修改相当于第二维区间加,查询在树状数组上二分,比一般的线段树还短= =可惜并不能跑过整体二分= =另外bzoj上的数据有 ...
- bzoj3110 [Zjoi2013]K大数查询——线段树套线段树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3110 外层权值线段树套内层区间线段树: 之所以外层权值内层区间,是因为区间线段树需要标记下传 ...
随机推荐
- Ubentu编译Android源码(AOSP)
前言: 一直想要编译一下Android 源码,之前去google 看,下载要下载repo. 当时很懵逼,repo 是个什么?(repo 是一个python 脚本,因为Android 源码git 仓库太 ...
- CakePHP中回调函数的使用
我们知道模型主要是用来处理数据的,有时我们想在模型操作之前或之后做一些额外逻辑处理,这时候就可以使用回调函数. 回调函数有很多种,beforeFind,afterFind,beforeValidate ...
- OSG的组成结构
OSG的组成结构 核心结构 OSG的功能类采用“命名空间+类名称”的形式来命名.命名空间的命名方式为:第一个单词小写,后继单词的首字母大写,例如osg.osgUtil.osgViewer等:类的名称则 ...
- mysql新手进阶03
当年忠贞为国酬,何曾怕断头? 如今天下红遍,江山靠谁守? 业未就,身躯倦,鬓已秋. 你我之辈,忍将夙愿,付与东流? 数据库结构如下: 仓库(仓库号, 城市, 面积) 订购单(职工号, 供应商号, 订购 ...
- angular-列表进行添加、编辑等操作时此行变色。
今天接触了一个功能,就是在一个列表中,当你新增或者对第N列进行编辑,删除等操作时这一列会变颜色.让用户对操作了哪行数据更认识更清晰,刷新之后这行的颜色就会消失.我觉得这个很有意思,记录一下.效果如下. ...
- 【CSV数据文件】
文件参数化设置方法
- 正则表达式 和 re 模块
正则表达式究竟是什么? 在一些网站注册的时候需要输入手机号码,当你输入一个错误的手机号码的时候,会提示你输入的手机号码格式错误 那么他究竟是如何判断的呢? 我们用Python代码进行表示: phone ...
- vector:动态数组
vector是C++标准模板库中的部分内容,中文偶尔译作“容器”,但并不准确.它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存 ...
- UVa 1583 - Digit Generator 解题报告 - C语言
1.题目大意 如果a加上a的各个数字之和得到b,则说a是b的生成元.给出n其中$1\le n\le 100000$,求其最小生成元,若没有解则输出0. 2.思路 使用打表的方法打出各个数字a对应的b, ...
- 【转载】2015Android 面试题 01
1.如何避免ANR? 答:ANR:Application Not Responding,五秒在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应. 当出现下列情况时,Andr ...