【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)
题意:有N个位置,M个操作。操作有两种,每次操作
如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
2操作中c<=Maxlongint
思路:这道题如果外层是位置的话就需要在外层区间更新 并不会写
所以需要外层权值,内层位置
然而常数太渣,BZOJ上过不去
并不想(会)写标记永久化
var t:array[..]of record
l,r:longint;
a,s:int64;
end;
op,x,y,z,d:array[..]of longint;
root:array[..]of longint;
n,m,up,i,tmp,n1,cnt:longint; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; function query(l,r,x,y,p:longint):int64;
var mid,k:longint;
tmp:int64;
begin
if p= then exit();
mid:=(l+r)>>;
if (t[p].a>)and(l<r) then
begin
tmp:=t[p].a;
if t[p].l= then begin inc(cnt); t[p].l:=cnt; end;
k:=t[p].l;
t[k].a:=t[k].a+tmp;
t[k].s:=t[k].s+tmp*(mid-l+);
if t[p].r= then begin inc(cnt); t[p].r:=cnt; end;
k:=t[p].r;
t[k].a:=t[k].a+tmp;
t[k].s:=t[k].s+tmp*(r-mid);
t[p].a:=;
end;
if (l>=x)and(r<=y) then exit(t[p].s);
query:=;
if x<=mid then query:=query+query(l,mid,x,y,t[p].l);
if y>mid then query:=query+query(mid+,r,x,y,t[p].r); end; procedure update(l,r,x,y:longint;var p:longint);
var mid,k:longint;
tmp:int64;
begin
if p= then begin inc(cnt); p:=cnt; end;
mid:=(l+r)>>;
if (t[p].a>)and(l<r) then
begin
tmp:=t[p].a;
if t[p].l= then begin inc(cnt); t[p].l:=cnt; end;
k:=t[p].l;
t[k].a:=t[k].a+tmp;
t[k].s:=t[k].s+tmp*(mid-l+);
if t[p].r= then begin inc(cnt); t[p].r:=cnt; end;
k:=t[p].r;
t[k].a:=t[k].a+tmp;
t[k].s:=t[k].s+tmp*(r-mid);
t[p].a:=;
end;
if (l>=x)and(r<=y) then
begin
t[p].a:=t[p].a+;
t[p].s:=t[p].s+r-l+;
exit;
end;
if x<=mid then update(l,mid,x,y,t[p].l);
if y>mid then update(mid+,r,x,y,t[p].r); t[p].s:=t[t[p].l].s+t[t[p].r].s;
end; procedure add(a,b,c:longint);
var l,r,k,mid:longint;
begin
l:=; r:=n+n+; k:=;
while l<r do
begin
mid:=(l+r)>>;
update(,n,a,b,root[k]);
if c<=mid then
begin
r:=mid; k:=k<<;
end
else
begin
l:=mid+; k:=(k<<)+;
end;
end;
update(,n,a,b,root[k]);
end; function ask(a,b:longint;c:int64):longint;
var l,r,mid,k:longint;
tmp:int64;
begin
l:=; r:=n+n+; k:=;
while l<r do
begin
mid:=(l+r)>>;
tmp:=query(,n,a,b,root[k<<]);
if tmp>=c then
begin
r:=mid; k:=k<<;
end
else
begin
l:=mid+; k:=(k<<)+;
c:=c-tmp;
end;
end;
exit(l);
end; begin readln(n,m);
for i:= to m do read(op[i],x[i],y[i],z[i]); for i:= to m do
if op[i]= then add(x[i],y[i],n+-z[i]) else writeln(n+-ask(x[i],y[i],z[i])); end.
2017.3.19
想了想还是学一波奇技淫巧
需要注意的是标记永久化只能用(l=x)and(r=y)的写法写
var t:array[..]of record
l,r:longint;
a,s:int64;
end;
op,x,y,z,d:array[..]of longint;
root:array[..]of longint;
n,m,up,i,tmp,n1,cnt:longint; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; procedure pushup(l,r,p:longint);
begin
t[p].s:=t[t[p].l].s+t[t[p].r].s+t[p].a*(r-l+);
end; function query(l,r,x,y,p:longint):int64;
var mid:longint;
ans:int64;
begin
if p= then exit();
if (l=x)and(r=y) then exit(t[p].s);
mid:=(l+r)>>;
query:=;
ans:=t[p].a*(y-x+);
if y<=mid then exit(query(l,mid,x,y,t[p].l)+ans)
else if x>mid then exit(query(mid+,r,x,y,t[p].r)+ans)
else exit(query(l,mid,x,mid,t[p].l)+query(mid+,r,mid+,y,t[p].r)+ans);
end; procedure update(l,r,x,y:longint;var p:longint);
var mid,k:longint;
tmp:int64;
begin
if p= then begin inc(cnt); p:=cnt; end;
mid:=(l+r)>>;
if (l=x)and(r=y) then
begin
t[p].a:=t[p].a+;
t[p].s:=t[p].s+r-l+;
exit;
end;
if y<=mid then update(l,mid,x,y,t[p].l)
else if x>mid then update(mid+,r,x,y,t[p].r)
else
begin
update(l,mid,x,mid,t[p].l);
update(mid+,r,mid+,y,t[p].r);
end;
pushup(l,r,p);
end; procedure add(a,b,c:longint);
var l,r,k,mid:longint;
begin
l:=; r:=n+n+; k:=;
while l<r do
begin
mid:=(l+r)>>;
update(,n,a,b,root[k]);
if c<=mid then
begin
r:=mid; k:=k<<;
end
else
begin
l:=mid+; k:=(k<<)+;
end;
end;
update(,n,a,b,root[k]);
end; function ask(a,b:longint;c:int64):longint;
var l,r,mid,k:longint;
tmp:int64;
begin
l:=; r:=n+n+; k:=;
while l<r do
begin
mid:=(l+r)>>;
tmp:=query(,n,a,b,root[k<<]);
if tmp>=c then
begin
r:=mid; k:=k<<;
end
else
begin
l:=mid+; k:=(k<<)+;
c:=c-tmp;
end;
end;
exit(l);
end; begin readln(n,m);
for i:= to m do read(op[i],x[i],y[i],z[i]); for i:= to m do
if op[i]= then add(x[i],y[i],n+-z[i]) else writeln(n+-ask(x[i],y[i],z[i])); end.
整体二分是二分答案,CDQ分治是二分操作序列
比树套树快2倍
var a,b:array[..]of record
l,r,id,op:longint;
w:int64;
end;
s1,s2:array[..]of int64;
flag,ans:array[..]of longint;
n,m,i,cnt:longint; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; procedure add(x,y:longint);
var i:longint;
begin
i:=x;
while i<=n do
begin
s1[i]:=s1[i]+y;
s2[i]:=s2[i]+y*x;
i:=i+lowbit(i);
end;
end; procedure update(a,b,c:longint);
begin
add(a,c); add(b+,-c);
end; function query(x:longint):int64;
var i:longint;
begin
i:=x; query:=;
while i> do
begin
query:=query+s1[i]*(x+)-s2[i];
i:=i-lowbit(i);
end;
end; function ask(a,b:longint):int64;
begin
exit(query(b)-query(a-));
end; procedure solve(x,y,l,r:longint);
var i,mid,pre,now:longint;
tmp:int64;
begin
if l=r then
begin
for i:=x to y do
if a[i].op= then ans[a[i].id]:=l;
exit;
end;
mid:=(l+r)>>;
pre:=x; now:=x;
for i:=x to y do
if a[i].op= then
begin
if a[i].w<=mid then
begin
update(a[i].l,a[i].r,);
flag[i]:=;
inc(now);
end
else flag[i]:=;
end
else
begin
tmp:=ask(a[i].l,a[i].r);
if tmp>=a[i].w then
begin
inc(now); flag[i]:=;
end
else
begin
flag[i]:=;
a[i].w:=a[i].w-tmp;
end;
end;
for i:=x to y do
if (a[i].op=)and(a[i].w<=mid) then update(a[i].l,a[i].r,-);
for i:=x to y do
if flag[i]= then
begin
b[now]:=a[i]; inc(now);
end
else
begin
b[pre]:=a[i]; inc(pre);
end;
for i:=x to y do a[i]:=b[i];
solve(x,pre-,l,mid);
solve(pre,y,mid+,r);
end; begin
assign(input,'bzoj3110.in'); reset(input);
assign(output,'bzoj3110.out'); rewrite(output);
read(n,m);
for i:= to m do
begin
read(a[i].op,a[i].l,a[i].r,a[i].w);
if a[i].op= then a[i].w:=n-a[i].w+
else
begin
inc(cnt); a[i].id:=cnt;
end;
end;
solve(,m,,*n+);
for i:= to cnt do writeln(n-ans[i]+);
close(input);
close(output);
end.
【BZOJ3110】K大数查询(权值线段树套线段树+标记永久化,整体二分)的更多相关文章
- [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)
[BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...
- 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...
- 洛谷P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树_标记永久化
Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...
- BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)
P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ...
- BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...
- 【BZOJ-3110】K大数查询 整体二分 + 线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6265 Solved: 2060[Submit][Sta ...
- 【BZOJ3110】[Zjoi2013]K大数查询 树套树
[BZOJ3110][Zjoi2013]K大数查询 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c,如果 ...
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 418 Solved: 235 [ Submit][ ...
随机推荐
- B. Hongcow Solves A Puzzle
http://codeforces.com/contest/745/problem/B 题目要求的是,给定一个图形,要求里面判断是否有矩形,且仅有一个 就是 XXX.... XXX...X 是不行的, ...
- 奇葩问题: lsattr -d /data 显示:----------I--e- /data/
奇葩问题 lsattr -d /data 显示:----------I--e- /data/ 问题影响: 其他权限中I(大写i) 目录下不能删除文件,不能添加文件 ================== ...
- [转]Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application (3 of 10)
本文转自:http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/sorting-fi ...
- .NET面试题解析(00)-系列文章索引
.NET面试题解析(01)-值类型与引用类型 .NET面试题解析(02)-拆箱与装箱 .NET面试题解析(03)-string与字符操作 .NET面试题解析(04)-类型.方法与继承 .NET面试题解 ...
- div里面整齐的字体样式,所有浏览器都兼容
<div id="wenda"> <div class="table_wd" > <div class="tr1&quo ...
- 【工具】sublime使用技巧
Ctrl+N 新建一个编辑区,Ctrl+Shift+C 或!加 Ctrl+E新建一个骨架完好的文件. Ctrl+Shift+P开启命令模式,sshtml 切换html语法. esc退出,Ctrl+`打 ...
- VUE学习,is 特性,转载来源:https://segmentfault.com/q/1010000007205176/
- 架构(Architecture)随想
架构(Architecture)的意义: 先不要看什么是架构,先看下architect是什么,没有错,它是建筑师,在一块空地上build高楼大厦的人,它是一个designer,设计好整个大楼,也是一个 ...
- 为什么jfinal的控制器不用单例模式
先假controller定采用单例模式,通常两种设计方式来存放 HttpServletRequest.HttpServletResponse 等对象,一是利用一个类似于 ActionContext 的 ...
- Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明
导航 目 录:Farseer.net轻量级ORM开源框架 目录 上一篇:没有了 下一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置 前言 V1.x版本终于到来了.本次 ...