[JSOI2009]等差数列
洛谷水过了,bzoj超时了
插入等差数列=》绝对是差分
至于能分成几个等差数列,浓浓的dp阴谋味;
好吧,正常的线段树收标记
维护
因为是差分=>且不用管数值
要跳过非连续等差数列首项
当前区间如果左右端点都不选有多少个等差数列 -> s[0]
当前区间如果只选左端点有多少个等差数列 -> s[1]
当前区间如果只选右端点有多少个等差数列 -> s[2]
当前区间如果左右端点都选有多少个等差数列 -> s[3]
#include<bits/stdc++.h>
#define re return
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define inc(i,l,r) for(int i=l;i<=r;++i)
#define dec(i,l,r) for(int i=l;i>=r;--i)
const int maxn=10e5+5;
using namespace std;
template<typename T>inline void rd(T&x)
{
char c;bool f=0;
while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
x=c^48;
while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
if(f)x=-x;
}
int n,m,cnt,b[maxn];
struct data
{
int l,r,s[4];
inline data operator+(data rs)const
{
data ans;
ans.l=l;ans.r=rs.r;
ans.s[0]=s[2]+rs.s[1]-(rs.l==r);
ans.s[0]=min(ans.s[0],s[2]+rs.s[0]);ans.s[0]=min(ans.s[0],s[0]+rs.s[1]);
ans.s[1]=s[3]+rs.s[1]-(rs.l==r);
ans.s[1]=min(ans.s[1],s[1]+rs.s[1]);ans.s[1]=min(ans.s[1],s[3]+rs.s[0]);
ans.s[2]=s[2]+rs.s[3]-(rs.l==r);
ans.s[2]=min(ans.s[2],s[2]+rs.s[2]);ans.s[2]=min(ans.s[2],s[0]+rs.s[3]);
ans.s[3]=s[3]+rs.s[3]-(rs.l==r);
ans.s[3]=min(ans.s[3],s[1]+rs.s[3]);ans.s[3]=min(ans.s[3],s[3]+rs.s[2]);
re ans;
}
};
struct node{
int val;data x;
}tree[maxn<<2];
inline void build(int rt,int l,int r)
{
if(l==r)
{
tree[rt].x.s[1]=tree[rt].x.s[2]=tree[rt].x.s[3]=1;
tree[rt].x.l=tree[rt].x.r=b[l+1]-b[l];
tree[rt].val=tree[rt].x.s[0]=0;
re ;
}
tree[rt].val=0;
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
tree[rt].x=tree[lson].x+tree[rson].x;
}
inline void pushdown(int rt)
{
tree[lson].val+=tree[rt].val;tree[rson].val+=tree[rt].val;
tree[lson].x.l+=tree[rt].val;tree[rson].x.l+=tree[rt].val;
tree[lson].x.r+=tree[rt].val;tree[rson].x.r+=tree[rt].val;
tree[rt].val=0;
re;
}
inline void add(int rt,int l,int r,int x,int y,int num)
{
if(x<=l&&r<=y)
{
tree[rt].val+=num;
tree[rt].x.l+=num;
tree[rt].x.r+=num;
re ;
}
if(tree[rt].val)pushdown(rt);
int mid=(l+r)>>1;
if(x<=mid)add(lson,l,mid,x,y,num);
if(y>mid)add(rson,mid+1,r,x,y,num);
tree[rt].x=tree[lson].x+tree[rson].x;
}
inline data query(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)re tree[rt].x;
if(tree[rt].val)pushdown(rt);
int mid=(l+r)>>1;
data v;
if(y<=mid)v=query(lson,l,mid,x,y);
else if(mid<x)v=query(rson,mid+1,r,x,y);
else v=query(lson,l,mid,x,y)+query(rson,mid+1,r,x,y);
tree[rt].x=tree[lson].x+tree[rson].x;
re v;
}
int main()
{
// freopen("in.txt","r",stdin);
rd(n);
inc(i,1,n)
rd(b[i]);
build(1,1,n-1);
char c;
int q,s,t,a,b;
rd(q);
inc(i,1,q)
{
while((c=getchar())!='A'&&c!='B');
if(c=='A')
{
rd(s),rd(t),rd(a),rd(b);
if(s!=1)add(1,1,n-1,s-1,s-1,a);
if(t!=n)add(1,1,n-1,t,t,-(a+b*(t-s)));
if(s!=t)add(1,1,n-1,s,t-1,b);
}
else {
rd(s),rd(t);
if(s==t)
{
printf("1\n");
continue;
}
else
{
data v=query(1,1,n-1,s,t-1);
printf("%d\n",v.s[3]);
}
}
}
re 0;
}