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. 冲刺NO.7

    Alpha冲刺第七天 站立式会议 项目进展 前期数据库设计所遗留的问题在今天得到了部分的解决,对物资管理所需要的数据内容进行了细化,但并未开始编写物资相关模块,主要精力还是放在项目的核心功能(信用管理 ...

  2. 学号:201621123032 《Java程序设计》第11周学习总结

    1:本周学习总结 1.1.:以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2:书面作业 2.1.: 源代码阅读:多线程程序BounceThread 1.1: BallRunnable类有什 ...

  3. 201621123043《java程序设计》第4周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键字:继承.覆盖.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. 1.3 可选:使用 ...

  4. memmove 和 memcpy的区别以及处理内存重叠问题

    区别: memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const v ...

  5. 使用caffe训练mnist数据集 - caffe教程实战(一)

    个人认为学习一个陌生的框架,最好从例子开始,所以我们也从一个例子开始. 学习本教程之前,你需要首先对卷积神经网络算法原理有些了解,而且安装好了caffe 卷积神经网络原理参考:http://cs231 ...

  6. nyoj 对决吃桃

    时间限制:3000 ms  |  内存限制:65535 KB 难度:0   描述 有一堆桃子不知数目,猴子第一天吃掉一半,又多吃了一个,第二天照此方法,吃掉剩下桃子的一半又多一个,天天如此,到第m天早 ...

  7. JAVA_SE基础——10.变量的作用域

    <pre name="code" class="java"> 上个月实在太忙了,从现在开始又可以静下心来写blog了. 变量的作用域指 可以使用此变 ...

  8. vuex - 项目结构目录及一些简单配置

    首先先正经的来一段官网的"忠告": vuex需要遵守的规则: 一.应用层级的状态应该集中到单个 store 对象中. 二.提交 mutation 是更改状态的唯一方法,并且这个过程 ...

  9. apacheds的客户端

    Apache DS管理的JAVA实现 LdapConnection connection = new LdapNetworkConnection("localhost", 1038 ...

  10. VCS使用学习笔记(1)——Verilog相关的仿真知识

    本文主要学习Verilog的仿真特性,以及仿真器对Verilog的处理,算是对Verilog知识的增量学习.本文内容与我的另一篇博文(http://www.cnblogs.com/IClearner/ ...