bzoj2653
CLJ神牛的可持久化论文的题目,果然厉害
其实第一步能想到后面就还是很简单的
首先是二分答案,转化为判定性问题
然后对于区间内的数,比他大的标为1,小的标为-1
显然,如果存在一个左右端点符合的区间使得这个区间和大于等于0(因为这里中位数是向下取整)
那么中位数一定是大于等于这个数的,这并不难理解
下面我们就是要快速求出左端点在[a,b],右端点[c,d]的最大区间和
显然可以转化为rmax[a,b]+sum[b+1,c-1]+lmax[c,d];
这里我们不难想到对于每个数建立一个线段树
线段树就是以位置为索引的,记录着区间左最大,区间右最大和区间和
考虑到树的形态都是相同的,我们可以先对数进行排序,然后建立主席树
平时我们的主席树都是在每个位置上建立一棵以键值为索引的线段树,而这里刚好相反
二分答案后就对对应数的线段树求区间最大和
type node=record
lm,rm,l,r,s:longint;
end; var tree:array[..*] of node;
a,c,h:array[..] of longint;
q:array[..] of longint;
j,m,t,ans,n,mid,i,l,r,w:longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure deal;
var i,j:longint;
begin
for i:= to do
for j:=i+ to do
if q[i]>q[j] then swap(q[i],q[j]);
end; procedure sort(l,r: longint);
var i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=a[(l+r) shr ];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if not(i>j) then
begin
swap(c[i],c[j]);
swap(a[i],a[j]);
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
procedure update(var a,b,c:node);
begin
a.s:=b.s+c.s;
a.lm:=max(b.lm,b.s+c.lm);
a.rm:=max(c.rm,c.s+b.rm);
end; function build(l,r:longint):longint;
var m,q:longint;
begin
inc(t);
if l=r then
begin
tree[t].s:=;
tree[t].lm:=;
tree[t].rm:=;
exit(t);
end
else begin
m:=(l+r) shr ;
q:=t;
tree[q].l:=build(l,m);
tree[q].r:=build(m+,r);
update(tree[q],tree[tree[q].l],tree[tree[q].r]);
exit(q);
end;
end; function work(l,r,last,x:longint):longint;
var m,q:longint;
begin
inc(t);
if l=r then
begin
tree[t].s:=-;
tree[t].lm:=-;
tree[t].rm:=-;
exit(t);
end
else begin
m:=(l+r) shr ;
q:=t;
if x<=m then
begin
tree[q].r:=tree[last].r;
tree[q].l:=work(l,m,tree[last].l,x);
end
else begin
tree[q].l:=tree[last].l;
tree[q].r:=work(m+,r,tree[last].r,x);
end;
update(tree[q],tree[tree[q].l],tree[tree[q].r]);
exit(q);
end;
end; function ask(l,r,x,ql,qr:longint):node; //传递整个node的的写法比我以前的写法要简单不少
var m:longint;
s,s1,s2:node;
begin
s.lm:=; s.rm:=; s.s:=;
if ql>qr then exit(s);
if (ql<=l) and (qr>=r) then exit(tree[x])
else begin
m:=(l+r) shr ;
if ql>m then exit(ask(m+,r,tree[x].r,ql,qr));
if qr<=m then exit(ask(l,m,tree[x].l,ql,qr));
s1:=ask(l,m,tree[x].l,ql,qr);
s2:=ask(m+,r,tree[x].r,ql,qr);
update(s,s1,s2);
exit(s);
end;
end; begin
readln(n);
for i:= to n do
begin
readln(a[i]);
c[i]:=i;
end;
sort(,n);
h[]:=build(,n);
for i:= to n do
h[i]:=work(,n,h[i-],c[i-]);
readln(m);
for i:= to m do
begin
for j:= to do
begin
read(q[j]);
q[j]:=(q[j]+ans) mod n+;
end;
readln;
deal;
l:=;
r:=n;
while l<=r do //二分答案
begin
mid:=(l+r) shr ;
w:=ask(,n,h[mid],q[],q[]).rm+ask(,n,h[mid],q[],q[]).lm+ask(,n,h[mid],q[]+,q[]-).s;
if w>= then
begin
ans:=a[mid];
l:=mid+;
end
else r:=mid-;
end;
writeln(ans);
end;
end.
bzoj2653的更多相关文章
- BZOJ2653 middle(二分答案+主席树)
与中位数有关的题二分答案是很常用的trick.二分答案之后,将所有大于它的看成1小于它的看成-1,那么只需要判断是否存在满足要求的一段和不小于0. 由于每个位置是1还是-1并不固定,似乎不是很好算.考 ...
- 【BZOJ2653】Middle(主席树)
[BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...
- BZOJ2653 middle 【主席树】【二分】*
BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...
- 【BZOJ2653】middle 二分+可持久化线段树
[BZOJ2653]middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个 ...
- [bzoj2653][middle] (二分 + 主席树)
Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b ...
- 【BZOJ-2653】middle 可持久化线段树 + 二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1298 Solved: 734[Submit][Status][Discu ...
- bzoj2653: middle
首先,对于每个询问,我们二分答案 然后对于序列中大于等于中位数的数,我们把它们置为1,小于中位数的数,置为-1 那么如果一个区间和大于等于0,那么就资磁,否则就不滋磁 这个区间和呢,我们可以用主席树维 ...
- bzoj2653:middle
思路:首先容易想到二分答案,但如何去check呢,对于一段区间[l,r],把所有小于答案的都赋值为-1,大于等于它的都赋值为1,然后求左端点在[a,b],右端点在[c,d]的最大子串和即可(也就是区间 ...
- 【BZOJ2653】【主席树+二分】middle
Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b ...
随机推荐
- IIS7报错:如果要使用托管的处理程序,请安装 ASP.NET
转载至码农SeraphWU IIS7报错:如果要使用托管的处理程序,请安装 ASP.NET 进入CMD 输入如下命令即可 "%WINDIR%\Microsoft.NET\Framework\ ...
- Jenkins integration for AngularJS code coverage
Install Jenkins plugins 'Cobertura' and 'HTML Publisher' 1. add Post-build Actions "Publish HTM ...
- java常用正则表达式
1.邮编 public static final String POSTAL_CODE = "^\\d{6}$"; 2. email(支持中文域名邮箱) 正则表达式 public ...
- 【html】【6】div浮动float
我想 当看完上面的必看链接,拥有一定的基础后也得7天左右, 记住 一定要看完,知道它都有什么,没学会不要紧,哪怕只是有个简单的概念也行, 随着后续的使用慢慢深入学习,现在开始div布局. 必看参考: ...
- 24种设计模式--门面模式【Facade Pattern】
大家都写过纸质的信件吧,比如给女朋友写情书什么的,写信的过程大家都还记得吧,先写信的内容,然后写信封,把信放到信封中,封好,投递到信箱中进行邮递,这个过程还是比较简单的,虽然简单,这四个步骤都是要跑的 ...
- Linux系统性能分析工具
1. uptime 2. htop 3. mpstat 4 . iostat 5. dstat 6. netstat 7. tcpdump 8. sar
- 图标字体的使用(fontello.com)字体推荐及使用技巧
网页设计中为了页面漂亮好看,图标是少不了,网页中使用的图标通常都是使用图片,使用图片图标的有很多弊端,如果你经常制作网页应该有一肚子埋怨. 使用图片图标的弊端 放大图标必须重新作图, 改变颜色必须开启 ...
- AS3.0声明静态属性和静态方法
静态属性的变量声明要加static,static var 名称:属性类型=值 静态属性的常量声明要加static或者const,并在声明时就要赋值.static||const var 名称:属性类型= ...
- [jQuery编程挑战]008 生成逗号分隔数字
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8&quo ...
- Hibernate 使用说明
Eclipse中hibernate连接mySQL数据库练习(采用的是hibernate中XML配置方式连接数据库,以后在更新其他方式的连接) Hibernate就是Java后台数据库持久层的框架,也是 ...