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. memmove 和 memcpy的区别以及处理内存重叠问题

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

  2. js解决IE8不支持html5,css3的问题(respond.js 的使用注意)

    IE8.0及以下不支持html5,css3的解析.目前为止IE8以下的版本使用率在10%左右,网站还是有必要兼容的. 1,在你的所有css最后判断引入两个js文件. html5.js  是用来让ie8 ...

  3. Web Api 利用 cors 实现跨域

    一.安装 cors 二.修改 Web.config <appSettings> <add key="cors:allowedMethods" value=&quo ...

  4. Web Service的工作原理

    Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的 ...

  5. Linux入门:增加用户,并赋予权限

    一.增加用户 1.增加用户,并指定主目录 # useradd –d /usr/sam -m sam此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录/usr/sam(/us ...

  6. Linux背景知识(1)RedHat和Centos

    Redhat有收费的商业版和免费的开源版,商业版的业内称之为RHEL(Red Hat Enterprise Linux)系列, 而这个CentOS(Community ENTerprise Opera ...

  7. SpringCloud的服务注册中心(二)注册中心服务端和两个微服务应用客户端

    一.构建EurekaServer工程 1.pom.xml 2.application.yml 3. EurekaServerApp.java 4.启动EurekaServer 二.构建部署 Eurek ...

  8. JS银行取款流程

     假设一个简单的ATM机的取款过程是这样的:首先提示用户输入密码(password),最多只能输入三次,超过3次则提示用户"密码错误,请取卡"结束交易.如果用户密码正确,再提示用户 ...

  9. AFNetWorking常用方法

    NSURLConnection,主要对NSURLConnection进行了进一步的封装,包含以下核心的类: AFURLConnectionOperation AFHTTPRequestOperatio ...

  10. Vue框架下的node.js安装教程

    Vue框架下的node.js安装教程 python服务器.php  ->aphche.java ->tomcat.   iis -->它是一个可以运行JAVASCRIPTR 的运行环 ...