【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][ ...
随机推荐
- GUI初步和frame&panel
java的话这个GUI其实不是什么重点,但我们也要学习,重点是学习这种图形编程的思路. java里面对于图形的一些类都封装在了AWT和它的一些子包里.AWT(抽象窗口开发包) 当 ...
- java 之冒泡排序
冒泡排序:可以想象成煮开水,气泡在瓶底的时候是比较小的,到达水面的时候达到最大. 冒泡排序的思想:先确定是升序还是降序,这里升序为例.每两个相邻的数字进行比较,前一个数字比后面一个数字大,就将两个数字 ...
- vue2.0 组件化
简单理解其实组件就是制作自定义的标签,这些标签在HTML中是没有的. 组件注册的是一个标签,而指令注册的是已有标签里的一个属性.在实际开发中我们还是用组件比较多,指令用的比较少. <!DOCTY ...
- 田字格布局html div
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- (一)Redis for Windows正确打开方式
目录 (一)Redis for Windows正确打开方式 (二)Redis for 阿里云公网连接 (三)Redis for StackExchange.Redis 下载地址 官网.中文网1 及 中 ...
- CentOS6.8 RPM包安装快速zabbix22
CentOS6.8 RPM包安装快速zabbix22 yum install -y epel-release # yum install -y httpd php php-devel mysql-se ...
- updating error reports database解决方案
Window--->Preferences--->General--->Startup and Shutdown--->取消勾选Eclipse Automated Error ...
- jQuery 开始动画,停止动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- CS2QS
inline QString MotorCS2QS(CString cs) { return QString::fromWCharArray((LPCTSTR)cs, cs.GetLength()); ...
- java正则表达式进阶运用20181023
直接上代码. package org.jimmy.autotranslate20181022.test; import java.util.regex.Matcher; import java.uti ...