给定一个长度为NN的序列{A}A,序列元素一开始均为0。
需要你设计数据结构并实现两种操作:
2.给出一个区间[L,R][L,R],你需要输出这个区间中最长连续等差数列的长度。
第一行有两个数NN,MM。代表序列长度与操作次数。
接下来M行,每行最开始有一个数opop。
如果op=0op=0,则后面有5个数L,R,a,k,pL,R,a,k,p,即第一种操作
如果op=1op=1,则后面有2个数L,RL,R,即第二种操作
对于每一个op == 1,输出一个数,表示最长连续等差序列长度。
我哭了,我调了一天,觉得代码没问题,最后发现是查询空间没多加个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; }