给定一个长度为NN的序列{A}A,序列元素一开始均为0。
需要你设计数据结构并实现两种操作:
2.给出一个区间[L,R][L,R],你需要输出这个区间中最长连续等差数列的长度。
Standard Input
第一行有两个数NN,MM。代表序列长度与操作次数。
接下来M行,每行最开始有一个数opop。
如果op=0op=0,则后面有5个数L,R,a,k,pL,R,a,k,p,即第一种操作
如果op=1op=1,则后面有2个数L,RL,R,即第二种操作
Standard Output
对于每一个op == 1,输出一个数,表示最长连续等差序列长度。
Samples
Input | Output |
---|---|
5 3 0 1 5 2 2 2 0 3 5 4 2 4 1 1 5 | 3 |
Constraints
我哭了,我调了一天,觉得代码没问题,最后发现是查询空间没多加个1,很普通的区间合并的线段树题,对于问题中的操作,把它转化成维护差值序列,这样求最长等差串就是求最长相同的数串
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+9;
struct rt{
ll lx,rx,lazy;int maxl,maxr,lmax;
}dat[maxn*4];
void pushUp(int k,int l,int r){
dat[k].lx=dat[k<<1].lx;
dat[k].rx=dat[k<<1|1].rx;
int mid=(l+r)>>1;
dat[k].maxl=dat[k<<1].maxl;
if(dat[k<<1].maxl==(mid-l+1)&&dat[k<<1].rx==dat[k<<1|1].lx){
dat[k].maxl=dat[k].maxl+dat[k<<1|1].maxl;
}
dat[k].maxr=dat[k<<1|1].maxr;
if(dat[k<<1|1].maxr==(r-mid)&&dat[k<<1].rx==dat[k<<1|1].lx){
dat[k].maxr=dat[k].maxr+dat[k<<1].maxr;
}
dat[k].lmax=max(dat[k<<1].lmax,dat[k<<1|1].lmax);
if(dat[k<<1].rx==dat[k<<1|1].lx){
dat[k].lmax=max(dat[k].lmax,dat[k<<1].maxr+dat[k<<1|1].maxl);
}
}
void build(int l,int r,int k){
if(l==r){
dat[k].lx=dat[k].rx=0;
dat[k].maxl=dat[k].maxr=dat[k].lmax=1;
return;
}
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
pushUp(k,l,r);
}
void pushDown(int k){
dat[k<<1].lx+=dat[k].lazy;
dat[k<<1].rx+=dat[k].lazy;
dat[k<<1|1].rx+=dat[k].lazy;
dat[k<<1|1].lx+=dat[k].lazy;
dat[k<<1].lazy+=dat[k].lazy;
dat[k<<1|1].lazy+=dat[k].lazy;
dat[k].lazy=0;
}
void add(int a,int b,int l,int r,int k,ll x){
if(a<=l&&r<=b){
dat[k].lx+=x;
dat[k].rx+=x;
dat[k].lazy+=x;
return ;
}
int mid=(l+r)>>1;
if(dat[k].lazy)pushDown(k);
if(a<=mid)add(a,b,l,mid,k<<1,x);
if(b>mid)add(a,b,mid+1,r,k<<1|1,x);
pushUp(k,l,r);
}
int query(int a,int b,int l,int r,int k){
if(a<=l&&r<=b)return dat[k].lmax;
if(dat[k].lazy)pushDown(k);
int mid=(l+r)>>1;
int lmax=0;
if(a<=mid&&b>mid){
int lx=min(dat[k<<1].maxr,(mid-a+1));
int ly=min(dat[k<<1|1].maxl,(b-mid));
if(dat[k<<1].rx==dat[k<<1|1].lx){
lmax=max(lmax,lx+ly);
}
}
if(a<=mid)lmax=max(lmax,query(a,b,l,mid,k<<1));
if(b>mid)lmax=max(lmax,query(a,b,mid+1,r,k<<1|1));
pushUp(k,l,r);
return lmax;
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
build(1,n,1);
int x,l,r,p;ll a,k;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&l,&r);
if(x==0){
scanf("%lld%lld%d",&a,&k,&p);
add(l,l,1,n,1,a);
add(l+1,p,1,n,1,k);
add(p+1,r,1,n,1,-k);
if(r+1<=n){
add(r+1,r+1,1,n,1,-(a+k*(2*p-l-r)));
}
}
else{
if(l==r)printf("1\n");
else printf("%d\n",query(l+1,r,1,n,1)+1);
}
}
return 0;
}