bzoj1558
好题,初看以为只要差分然后维护相同的段数目
但是请注意下面的情况
2 3 5 8 9
1 2 3 4 这显然答案是3而不是4
因此我们还要再维护ld,rd表示左右单独的段长度
和s表示不包括左右单独的段,中间部分最少划分成几个等差数列
具体维护见程序,比较复杂,但其实不难
这题还有一个坑爹的地方,我一开始忘开int64本地测数据竟然全能过
但是交上去就WA……感人肺腑
type node=record
l,r:int64;
ld,rd,s:longint;
end; var tree:array[..*] of node;
lazy:array[..*] of int64;
a:array[..] of longint;
n,m,i,x0,y0,x,y,p,q:longint;
z:int64;
ans:node;
ch:char; procedure update(var a:node;x,y:node);
begin
a.l:=x.l;
a.r:=y.r;
a.ld:=x.ld;
if x.s= then //x.s=说明左部分全是单独的(没有连续出现2个及以上的)
begin
if x.r<>y.l then inc(a.ld,y.ld)
else dec(a.ld);
end;
a.rd:=y.rd;
if y.s= then
begin
if x.r<>y.l then inc(a.rd,x.rd)
else dec(a.rd);
end;
a.s:=x.s+y.s;
if x.s= then //以下请自行理解
begin
if x.r=y.l then
begin
if y.s= then inc(a.s)
else if (y.ld>) then inc(a.s,(y.ld-) shr +);
end;
end
else if x.rd> then
begin
if x.r=y.l then
begin
inc(a.s,(x.rd-) shr );
if y.s= then inc(a.s)
else if (y.ld>) then inc(a.s,(y.ld-) shr +);
end
else if y.s> then
inc(a.s,(x.rd+y.ld) shr );
end
else begin
if x.r=y.l then
begin
if (y.s>) and (y.ld>) then inc(a.s,(y.ld-) shr );
if (y.s>) and (y.ld=) then dec(a.s);
end
else if (y.s>) and (y.ld>) then inc(a.s,y.ld shr );
end;
end; procedure push(i:longint);
begin
inc(lazy[i*],lazy[i]);
inc(tree[i*].l,lazy[i]);
inc(tree[i*].r,lazy[i]);
inc(lazy[i*+],lazy[i]);
inc(tree[i*+].l,lazy[i]);
inc(tree[i*+].r,lazy[i]);
lazy[i]:=;
end; procedure build(i,l,r:longint);
var m:longint;
begin
if l=r then
begin
tree[i].l:=a[l+]-a[l];
tree[i].r:=a[l+]-a[l];
tree[i].ld:=;
tree[i].rd:=;
end
else begin
m:=(l+r) shr ;
build(i*,l,m);
build(i*+,m+,r);
update(tree[i],tree[i*],tree[i*+]);
end;
end; procedure add(i,l,r:longint);
var m:longint;
begin
if (x<=l) and (y>=r) then
begin
inc(tree[i].l,z);
inc(tree[i].r,z);
lazy[i]:=lazy[i]+z;
end
else begin
if lazy[i]<> then push(i);
m:=(l+r) shr ;
if x<=m then add(i*,l,m);
if y>m then add(i*+,m+,r);
update(tree[i],tree[i*],tree[i*+]);
end;
end; function ask(i,l,r:longint):node;
var s,s1,s2:node;
m:longint;
begin
if (x<=l) and (y>=r) then exit(tree[i])
else begin
m:=(l+r) shr ;
if lazy[i]<> then push(i);
if y<=m then exit(ask(i*,l,m));
if x>m then exit(ask(i*+,m+,r));
s1:=ask(i*,l,m);
s2:=ask(i*+,m+,r);
update(s,s1,s2);
exit(s);
end;
end; begin
readln(n);
for i:= to n do
readln(a[i]);
dec(n);
build(,,n);
readln(m);
for i:= to m do
begin
read(ch);
if ch='A' then
begin
readln(x0,y0,p,q);
if x0> then //修改要分三种情况
begin
x:=x0-; y:=x0-; z:=p;
add(,,n);
end;
if y0<=n then
begin
x:=y0; y:=y0; z:=-int64(p)-int64(y0-x0)*int64(q);
add(,,n);
end;
if x0<y0 then
begin
x:=x0; y:=y0-; z:=q;
add(,,n);
end;
end
else begin
readln(x,y);
if y=x then writeln()
else begin
dec(y);
ans:=ask(,,n);
if ans.s= then writeln((y-x+) shr ) //全是单独的可以直接算出来
else writeln(ans.s+(ans.ld+) shr +(ans.rd+) shr );
end;
end;
end;
end.
bzoj1558的更多相关文章
- 【BZOJ1558】等差数列(线段树)
[BZOJ1558]等差数列(线段树) 题面 BZOJ 题解 可以说这道题已经非常毒瘤了 怎么考虑询问操作? 如果直接将一段数分解为等差数列? 太麻烦了.... 考虑相邻的数做差, 这样等差数列变为了 ...
- BZOJ1558 [JSOI2009]等差数列 【线段树】
题目链接 BZOJ1558 题解 等差数列,当然是差分一下 差分值相同的连续位置形成等差数列,我们所选的两个等差数列之间可以有一个位置舍弃 例如: \(1 \; 2 \; 3 \; 6 \; 8 \; ...
- [bzoj1558][JSOI2009]等差数列
题目:给定n个数,m个操作,每次给一段区间加一个等差数列或者询问一段区间至少要用多少个等差数列来表示.$n,m\leqslant 10^{5}$ 题解:老套路,维护差分数组,修改操作变成了两个单点加和 ...
- 洛谷P4243/bzoj1558 [JSOI2009]等差数列(线段树维护差分+爆炸恶心的合并)
题面 首先感谢这篇题解,是思路来源 看到等差数列,就会想到差分,又有区间加,很容易想到线段树维护差分.再注意点细节,\(A\)操作完美解决 然后就是爆炸恶心的\(B\)操作,之前看一堆题解的解释都不怎 ...
- BZOJ1558 等差数列
题目链接:戳我 实话实话,看了几篇题解真的没看懂,我觉得讲的都有问题.这里对于线段树维护的s写了一点我自己的理解. 看到等差数列,我们考虑对数列做差,这样如果是等差数列,那么值应该相等.(比较容易维护 ...
- 线段树 by yyb
线段树 by yyb Type1 维护特殊信息 1.[洛谷1438]无聊的数列 维护一个数列,两种操作 1.给一段区间加上一个等差数列 2.单点询问值 维护等差数列 不难发现,等差数列可以写成\(ad ...
- OI题目类型总结整理
## 本蒟蒻的小整理qwq--持续更新(咕咕咕) 数据结构 数据结构 知识点梳理 数据结构--线段树 推荐yyb dalao的总结--戳我 以后维护线段树还是把l,r写到struct里面吧,也别写le ...
随机推荐
- Mysql下在某一列后即表的某一位置添加新列的sql语句
Mysql简介 MySQL是一个开放源码的小型关联式数据库管理系统,开发者为瑞典MySQL AB公司.MySQL被广泛地应用在Internet上的中小型网站中.由于其体积小.速度快.总体拥有成本低,尤 ...
- 学习笔记_第一个strut程序_之中文乱码,过滤器解决方案及过程总结
1. 第一次碰到加过滤器的过程,就是在学习struct1的时候,中文乱码 几个需要注意的关键字 2.什么叫package 所谓package就是打包的意思,就是说以下程序都是处于这个包内,所以一开始 ...
- /etc/shadow
这样,用户帐户本身在 /etc/passwd 中定义.Linux 系统包含一个 /etc/passwd 的同伴文件,叫做 /etc/shadow.该文件不像 /etc/passwd,只有对于 root ...
- onMouseDown onMouseUp onMouseMove(移动鼠标图像大小变化)
- 开发一个完整的JavaScript组件
作为一名开发者,大家应该都知道在浏览器中存在一些内置的控件:Alert,Confirm等,但是这些控件通常根据浏览器产商的不同而形态各异,视觉效果往往达不到UI设计师的要求.更重要的是,这类内置控件的 ...
- windows server 2003 禁止开机显示“关闭事件跟踪”
关机事件跟踪(Shutdown Event Tracker)也是Windows server 2003区别于其他工作站系统的一个设置,对于服务器来说这是一个必要的选择,但是对于工作站系 ...
- Poj 2115 C Looooops(exgcd变式)
C Looooops Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22704 Accepted: 6251 Descripti ...
- C++ 智能指针auto_ptr详解
1. auto_ptr 的设计动机: 函数操作经常依照下列模式进行: 获取一些资源 执行一些动作 释放所获取的资源 那么面对这些资源的释放问题就会出现下面的两种情况: 一开始获得的资源被绑定于局部对象 ...
- IOS 学习笔记 2015-03-24 OC-API-常用结构体
一 标题 常用结构体 二 API 1 NSRange 表示一个范围 A 实例化 NSRange rg={3,5};//第一参数是起始位置第二个参数是长度 B 实例化 NSRange rg2=NSMak ...
- 上传文件到服务器端后进一步推送到sftp服务器
扩展安装 要想sftp服务端发送文件,就需要php脚本具有作为ssh客户端的能力,所以需先为php安装如下扩展 openssl openssl-dev libssh php ssh 扩展 按照下面的命 ...