好题,初看以为只要差分然后维护相同的段数目
但是请注意下面的情况
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的更多相关文章

  1. 【BZOJ1558】等差数列(线段树)

    [BZOJ1558]等差数列(线段树) 题面 BZOJ 题解 可以说这道题已经非常毒瘤了 怎么考虑询问操作? 如果直接将一段数分解为等差数列? 太麻烦了.... 考虑相邻的数做差, 这样等差数列变为了 ...

  2. BZOJ1558 [JSOI2009]等差数列 【线段树】

    题目链接 BZOJ1558 题解 等差数列,当然是差分一下 差分值相同的连续位置形成等差数列,我们所选的两个等差数列之间可以有一个位置舍弃 例如: \(1 \; 2 \; 3 \; 6 \; 8 \; ...

  3. [bzoj1558][JSOI2009]等差数列

    题目:给定n个数,m个操作,每次给一段区间加一个等差数列或者询问一段区间至少要用多少个等差数列来表示.$n,m\leqslant 10^{5}$ 题解:老套路,维护差分数组,修改操作变成了两个单点加和 ...

  4. 洛谷P4243/bzoj1558 [JSOI2009]等差数列(线段树维护差分+爆炸恶心的合并)

    题面 首先感谢这篇题解,是思路来源 看到等差数列,就会想到差分,又有区间加,很容易想到线段树维护差分.再注意点细节,\(A\)操作完美解决 然后就是爆炸恶心的\(B\)操作,之前看一堆题解的解释都不怎 ...

  5. BZOJ1558 等差数列

    题目链接:戳我 实话实话,看了几篇题解真的没看懂,我觉得讲的都有问题.这里对于线段树维护的s写了一点我自己的理解. 看到等差数列,我们考虑对数列做差,这样如果是等差数列,那么值应该相等.(比较容易维护 ...

  6. 线段树 by yyb

    线段树 by yyb Type1 维护特殊信息 1.[洛谷1438]无聊的数列 维护一个数列,两种操作 1.给一段区间加上一个等差数列 2.单点询问值 维护等差数列 不难发现,等差数列可以写成\(ad ...

  7. OI题目类型总结整理

    ## 本蒟蒻的小整理qwq--持续更新(咕咕咕) 数据结构 数据结构 知识点梳理 数据结构--线段树 推荐yyb dalao的总结--戳我 以后维护线段树还是把l,r写到struct里面吧,也别写le ...

随机推荐

  1. nyoj914Yougth的最大化(二分搜索 + 贪心)

    Yougth的最大化 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 Yougth现在有n个物品的重量和价值分别是Wi和Vi,你能帮他从中选出k个物品使得单位重量的价值最大吗 ...

  2. OC加强-day04

    #pragma mark 00知识回顾 //定义一个函数 函数没有返回值函数有一个参数:返回值是double 参数是两个int的block void test(int a); void test(do ...

  3. Objective-C MRC多个对象相互引用的内存管理

    在MRC环境下,假定CTRoom对象是CTPerson的一个成员变量,那么修改CTRoom对象时应注意,代码如下: - (void) setRoom:(CTRoom *) room { //需判断新旧 ...

  4. JavaScript之String()和.toString()

    JS中 转换字符串的方法有两个 一个String(),一个.toString(). 通常情况下 这两种使用没有太大的区别.但是需要注意几点: undefined: toString() var tes ...

  5. java I/O技术

    一.流的分类 Java的流类大部分都是由InputStream.OutputStream.Reader和Writer这四个抽象类派生出来的 (1)按数据流向 输入流(InputStream类和Read ...

  6. Cogs 1298.通讯问题

    1298.通讯问题 ★ 输入文件:jdltt.in 输出文件:jdltt.out 简单对比 时间限制:1 s 内存限制:128 MB [题目描述] 一个篮球队有n个篮球队员,每个队员都有联系方式(如电 ...

  7. Mac OS 安装 Port

    简介 MacPorts类似与apt-get以及yum等软件包管理工具,可以方便的进行安装与卸载软件的功能,同时可以自动安装软件包的依赖,非常方便,同类的还有brew等工具. 安装 下载MacPorts ...

  8. asmdisk 丢失问题一次记录

    环境 vm12 workstation ,11.2R 在安装RAC 第二台机器不显示磁盘的是问题 , oracleasm listdisks 查询没有结果 , 于是执行 oracleasm scand ...

  9. 二进制方式快速安装MySQL数据库命令集合

    二进制方式快速安装MySQL数据库命令集合 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 1.安装mysql ls mysql ...

  10. phpstorm使用技巧

    确实很好用,不过还是要看一些方法 转自:http://blog.sina.com.cn/s/blog_488193d70102vk7e.html 2, 关联DOC文档: 右键External Libr ...