Description

Solution

把原数组变为差分数组,然后剩下的就十分显然了

区间查询用线段树维护

修改操作就是区间加法和两个单点修改

一个等差数列实际上就是 开头一个数字+数值相等的一段

唯一的难点在于讨论这个开头的数字的去向

在线段树合并的时候

\(mid\) 左右两个元素如果相等的话是可以合并的,所以还需要做讨论

所以我们可以先不把左右两端点列入考虑对象,然后在合并时再讨论去向,综上需要维护的东西有:

1.区间的左右两个端点都不列入考虑的等差数列数量

2.区间的左端点列入考虑

3.区间的右段点列入考虑

4.区间的左右端点都列入考虑

\(4\) 就是我们要求的,每一种情况的转移都是类似的,转移我们可以分三种情况讨论:

1.左边的右端点和右边的左端点本身作为了等差数列的开头,左边的和右边的等差数列直接合并,如果相邻元素相等,则合为一个等差数列

2.左边的右端点自成一个等差数列

3.右边的左端点自成一个等差数列

#include<bits/stdc++.h>
#define ls (o<<1)
#define rs (o<<1|1)
using namespace std;
const int N=1e5+10;
int n,Q,a[N],w[N],la[N*4];
struct sub{
int a[4],wl,wr;
}t[N*4];
inline sub upd(sub a,sub b){
sub c;
c.a[0]=min(a.a[2]+b.a[1]-(a.wr==b.wl),min(a.a[0]+b.a[1],a.a[2]+b.a[0]));
c.a[1]=min(a.a[3]+b.a[1]-(a.wr==b.wl),min(a.a[1]+b.a[1],a.a[3]+b.a[0]));
c.a[2]=min(a.a[2]+b.a[3]-(a.wr==b.wl),min(a.a[2]+b.a[2],a.a[0]+b.a[3]));
c.a[3]=min(a.a[3]+b.a[3]-(a.wr==b.wl),min(a.a[3]+b.a[2],a.a[1]+b.a[3]));
c.wl=a.wl;c.wr=b.wr;
return c;
}
inline void build(int l,int r,int o){
if(l==r){
t[o].wl=t[o].wr=w[l];
t[o].a[1]=t[o].a[2]=t[o].a[3]=1;t[o].a[0]=0;
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls);build(mid+1,r,rs);
t[o]=upd(t[ls],t[rs]);
}
inline void pushdown(int o){
if(!la[o])return ;
int k=la[o];la[o]=0;
t[ls].wl+=k;t[ls].wr+=k;la[ls]+=k;
t[rs].wl+=k;t[rs].wr+=k;la[rs]+=k;
}
inline sub qry(int l,int r,int o,int sa,int se){
if(sa<=l && r<=se)return t[o];
int mid=(l+r)>>1;sub ret;
pushdown(o);
if(se<=mid)ret=qry(l,mid,ls,sa,se);
else if(sa>mid)ret=qry(mid+1,r,rs,sa,se);
else ret=upd(qry(l,mid,ls,sa,mid),qry(mid+1,r,rs,mid+1,se));
t[o]=upd(t[ls],t[rs]);
return ret;
}
inline void Modify(int l,int r,int o,int sa,int se,int z){
if(sa<=l && r<=se){
la[o]+=z;t[o].wl+=z;t[o].wr+=z;
return ;
}
pushdown(o);
int mid=(l+r)>>1;
if(se<=mid)Modify(l,mid,ls,sa,se,z);
else if(sa>mid)Modify(mid+1,r,rs,sa,se,z);
else Modify(l,mid,ls,sa,mid,z),Modify(mid+1,r,rs,mid+1,se,z);
t[o]=upd(t[ls],t[rs]);
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<n;i++)w[i]=a[i+1]-a[i];
build(1,n-1,1);
int x,y,p,q;char op[3];
scanf("%d",&Q);
while(Q--){
scanf("%s%d%d",op,&x,&y);
if(op[0]=='B'){
if(x==y)puts("1");
else printf("%d\n",qry(1,n-1,1,x,y-1).a[3]);
}
else{
scanf("%d%d",&p,&q);
if(x>1)Modify(1,n-1,1,x-1,x-1,p);
if(y<n)Modify(1,n-1,1,y,y,-p-(y-x)*q);
if(x<y)Modify(1,n-1,1,x,y-1,q);
}
}
return 0;
}

bzoj 1558: [JSOI2009]等差数列的更多相关文章

  1. BZOJ.1558.[JSOI2009]等差数列(线段树 差分)

    BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...

  2. BZOJ 1444:[JSOI2009]有趣的游戏

    BZOJ 1444:[JSOI2009]有趣的游戏 题目链接 首先我们建出Trie图,然后高斯消元. 我们设\(f_i\)表示经过第\(i\)个点的期望次数: \[ f_x=\sum i\cdot p ...

  3. [BZOJ 2257][JSOI2009]瓶子和燃料 题解(GCD)

    [BZOJ 2257][JSOI2009]瓶子和燃料 Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了. 有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子 ...

  4. 洛谷 P4571 BZOJ 2257 [JSOI2009]瓶子和燃料

    bzoj题目链接 上面hint那里是选择第2个瓶子和第3个瓶子 Time limit 10000 ms Memory limit 131072 kB OS Linux Source Jsoi2009 ...

  5. [JSOI2009]等差数列

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1558 题解: 考虑这么用线段树进行维护,由于他有区间修改等差数列 很容易想到可以用差分数组来维 ...

  6. BZOJ 3357: [Usaco2004]等差数列

    3357: [Usaco2004]等差数列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 338  Solved: 160[Submit][Statu ...

  7. BZOJ 1452: [JSOI2009]Count 二维树状数组

    1452: [JSOI2009]Count Description Input Output Sample Input Sample Output 1 2 HINT Source 题解:设定C[101 ...

  8. BZOJ 2257: [Jsoi2009]瓶子和燃料 裴蜀定理

    2257: [Jsoi2009]瓶子和燃料 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  9. [BZOJ 1559] [JSOI2009] 密码 【AC自动机DP】

    题目链接:BZOJ - 1559 题目分析 将给定的串建成AC自动机,然后在AC自动机上状压DP. 转移边就是Father -> Son 或 Now -> Fail. f[i][j][k] ...

随机推荐

  1. Beta Scrum Day 2

    听说

  2. C语言博客作业—数据类型

    一.PTA实验作业 题目1: 1. 本题PTA提交列表 2. 设计思路 (2)if(输入的n为奇数){ for(行数小于n/2+1时){ for(空格数等于n-2*k+1) printf(" ...

  3. APP案例分析--扇贝单词

    APP案例分析 一.调研 1.第一次上手   第一次使用时,一进APP,有一个每日一句,然后就是登录界面.有点不舒服,我都还不知道你这个APP好不好用,不让我体验一下就要注册.简单的测试了我的英语水平 ...

  4. Oracle查询用户权限

    Oracle查询用户权限 -- 确定角色的权限select * from role_tab_privs ;              包含了授予角色的对象权限select * from role_ro ...

  5. 201621123043 《Java程序设计》第6周学习总结

    1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖面向对象的 ...

  6. LR回放https协议脚本失败: 错误 -27778: 在尝试与主机“www.baidu.com”connect 时发生 SSL 协议错误

    今天用LR录制脚本协议为https协议,回放脚本时出现报错: Action.c(14): 错误 -27778: 在尝试与主机"www.baidu.com"connect 时发生 S ...

  7. python之路--day6--字符编码

    一.知识储备 cpu--控制和运算 内存--暂时存储cpu需要的数据 硬盘--永久保存数据2.文本编辑器的原理存储原理 1,启动文本编辑器 2,在编辑器上输入内容---此时输入内容还在内存上 3,保存 ...

  8. 韩顺平dedecms讲解上课记录

    感谢韩顺平: 如何打开php的gd库,通过php设置->php扩展-->phpdb库;打上勾就行: dede存在四张十分重要的表,channeltype,模型表最原始的发源arctype: ...

  9. c 语言常量

    1,整数常量 整数常量可以是十进制.八进制或十六进制的常量.前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制. 整数常量也可以带一个后缀,后缀是 U 和 L 的组合 ...

  10. Linq 透明标识符

    IEnumerable<Person> list = new List<Person> { , Id = }, , Id = }, , Id = }, , Id = }, , ...