题意:有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大数查询(权值线段树套线段树+标记永久化,整体二分)的更多相关文章

  1. [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)

    [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...

  2. 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  3. BZOJ3110[Zjoi2013]K大数查询——权值线段树套线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是 ...

  4. 洛谷P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树_标记永久化

    Code: #include <cstdio> #include <algorithm> #include <string> #include <cstrin ...

  5. BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  6. P3332 [ZJOI2013]K大数查询(线段树套线段树+标记永久化)

    P3332 [ZJOI2013]K大数查询 权值线段树套区间线段树 把插入的值离散化一下开个线段树 蓝后每个节点开个线段树,维护一下每个数出现的区间和次数 为了防止MLE动态开点就好辣 重点是标记永久 ...

  7. BZOJ3110 [Zjoi2013]K大数查询 树套树 线段树 整体二分 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3110 题意概括 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位 ...

  8. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  9. 【BZOJ3110】[Zjoi2013]K大数查询 树套树

    [BZOJ3110][Zjoi2013]K大数查询 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c,如果 ...

  10. BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 418   Solved: 235 [ Submit][ ...

随机推荐

  1. 如何使用mysqldump命令导入导出数据库下的数据或表结构(远程or本地都适合)

    不多说,直接上干货! https://www.cloudera.com/documentation/manager/5-1-x/Cloudera-Manager-Installation-Guide/ ...

  2. ATM机(非函数版)

    #include<stdio.h>#include<stdlib.h>int main(void){char zhangHao[]="123";int mi ...

  3. Oracle 用到的服务

    1.Oracle ORCL VSS Writer Service Oracle卷映射拷贝写入服务,VSS(Volume ShadowCopy Service)能够让存储基础设备(比如磁盘,阵列等)创建 ...

  4. MySQL多表

    一.外键 1.外键:链接两张表的字段,通过主表的主键和从表的外键来描述主外键关系,呈现的是一对多的关系.例如:商品类别(一)对商品(多),主表:商品类别表,从表:商品表. 2.外键的特点:从表外键的值 ...

  5. 【译】x86程序员手册36-9.9异常汇总

    9.9 Exception Summary 异常汇总 Table 9-6 summarizes the exceptions recognized by the 386. Table 9-6. Exc ...

  6. 【转帖】迅为iTOP-iMX6开发板 Ubuntu系统下WiFi模块mt6620的移植

    本文转自迅为论坛 :http://www.topeetboard.com 文档提供的文件如下. wpa_supplicant 拷贝到开发板 Ubuntu 系统的 /sbin 目录下,如何移植 wpa_ ...

  7. C/S模型:TCP,UDP构建客户端和服务器端(BIO实现

    Java中提供了socket编程来构建客户端和服务器端 TCP构建服务器端的步骤:(1)bind:绑定端口号(2)listen:监听客户端的连接请求(3)accept:返回和客户端连接的实例(4)re ...

  8. CREATE SCHEMA - 定义一个新的模式

    SYNOPSIS CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ] CREATE SCHEM ...

  9. shellinabox的安装使用

    一.简介 Shell In A Box(发音是shellinabox)是一款基于Web的终端模仿器,由Markus Gutschke开辟而成.它有内置的Web办事器,在指定的端口上作为一个基于Web的 ...

  10. Mac OS 使用asio库

    下载地址:http://sourceforge.net/projects/asio/files/asio/1.12.2%20%28Stable%29/ 本人下载的版本:asio-1.12.2 1,本人 ...