P11334 solution
对原数列差分,则一个区间
区间加等差数列即在开头加
时间复杂度
:::info[P11334]
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ir(i,a,b) for(int i=b;i>=a;i--)
#define db double
#define ld long double
#define YES cout<<"YES\n"
#define Yes cout<<"Yes\n"
#define NO cout<<"NO\n"
#define No cout<<"No\n"
#define re return
#define len(str) (str.length())
#define inr(L,R,l,r) (l<=L and R<=r)
#define ofr(L,R,l,r) (L>r or l>R)
#define lowbit(x) (x&(-x))
#define tn2 tuple<node*,node*>
#define tn3 tuple<node*,node*,node*>
#define mt make_tuple
#define np nullptr
#define ioo cin.tie(0)->sync_with_stdio(0);cout.tie(0)->sync_with_stdio(0);
#define popc __builtin_popcount
using namespace std;
const int maxn=3e5+114;
int n,q;
ll d[maxn];
struct node
{
ll w,lval,rval,lc,rc,lzy1,lzy2,len,ans;
bool flag1,flag2,empty;
node(bool ff=0)
{
flag1=flag2=0;
lzy1=lzy2=0;empty=ff;
}
} t[maxn<<2],non(1);
node pushup(node a,node b)
{
if(a.empty) re b;
if(b.empty) re a;
node c;
c.len=a.len+b.len;
c.w=a.w+b.w;
c.lval=a.lval;c.rval=b.rval;
c.lc=a.lc;
c.rc=b.rc;
if(a.lc==a.len and a.rval==b.lval) c.lc=a.len+b.lc;
if(b.rc==b.len and b.lval==a.rval) c.rc=a.rc+b.len;
c.ans=max(max(max(a.ans,b.ans),max(a.lc,a.rc)),max(b.lc,b.rc));
if(a.rval==b.lval) c.ans=max(c.ans,a.rc+b.lc);
re c;
}
void build(int u,int L,int R)
{
if(L==R)
{
t[u].lval=t[u].rval=t[u].w=d[L];
t[u].len=1;
t[u].lc=t[u].rc=1;
t[u].ans=1;
}else{
int M=L+R>>1;
build(2*u,L,M);
build(2*u+1,M+1,R);
t[u]=pushup(t[2*u],t[2*u+1]);
}
}
void tagset(int u,ll x)
{
t[u].flag1=1;t[u].flag2=0;
t[u].lzy1=x;t[u].lzy2=0;
t[u].w=x*t[u].len;
t[u].lc=t[u].rc=t[u].len;
t[u].lval=x;t[u].rval=x;
t[u].ans=t[u].len;
}
void tagadd(int u,ll x)
{
t[u].flag2=1;
t[u].lzy2+=x;
t[u].w+=x*t[u].len;
t[u].lval+=x;t[u].rval+=x;
}
void pushdown(int u)
{
if(t[u].flag1)
{
tagset(2*u,t[u].lzy1);
tagset(2*u+1,t[u].lzy1);
t[u].lzy1=t[u].flag1=0;
}
if(t[u].flag2)
{
tagadd(2*u,t[u].lzy2);
tagadd(2*u+1,t[u].lzy2);
t[u].lzy2=t[u].flag2=0;
}
}
node query(int u,int L,int R,int l,int r)
{
if(inr(L,R,l,r)) re t[u];
else if(ofr(L,R,l,r)) re non;
else
{
int M=L+R>>1;
pushdown(u);
re pushup(query(2*u,L,M,l,r),query(2*u+1,M+1,R,l,r));
}
}
void updset(int u,int L,int R,int l,int r,ll x)
{
if(inr(L,R,l,r))
{
tagset(u,x);
}else if(!ofr(L,R,l,r))
{
int M=L+R>>1;
pushdown(u);
updset(2*u,L,M,l,r,x);
updset(2*u+1,M+1,R,l,r,x);
t[u]=pushup(t[2*u],t[2*u+1]);
}
}
void updadd(int u,int L,int R,int l,int r,ll x)
{
if(inr(L,R,l,r)) tagadd(u,x);
else if(!ofr(L,R,l,r))
{
int M=L+R>>1;
pushdown(u);
updadd(2*u,L,M,l,r,x);
updadd(2*u+1,M+1,R,l,r,x);
t[u]=pushup(t[2*u],t[2*u+1]);
}
}
int main()
{
ioo;
cin>>n>>q;
rep(i,1,n) cin>>d[i];
ir(i,1,n) d[i]-=d[i-1];
build(1,1,n);
while(q--)
{
ll l,r,s,c,o;
cin>>o>>l>>r;
if(o<=2) cin>>s>>c;
if(o==1)
{
ll rv;
if(r!=n) rv=query(1,1,n,1,r+1).w;
if(l!=r) updadd(1,1,n,l+1,r,c);
updadd(1,1,n,l,l,s);
if(r!=n) updset(1,1,n,r+1,r+1,rv-query(1,1,n,1,r).w);
}else if(o==2)
{
ll lv,rv;
if(l!=1) lv=query(1,1,n,1,l-1).w;
else lv=0;
if(r!=n) rv=query(1,1,n,1,r+1).w;
else rv=0;
updset(1,1,n,l,l,s-lv);
if(l!=r) updset(1,1,n,l+1,r,c);
lv=query(1,1,n,1,r).w;
if(r!=n) updset(1,1,n,r+1,r+1,rv-lv);
}
else{
if(l!=r) cout<<query(1,1,n,l+1,r).ans+1<<'\n';
else cout<<1<<'\n';
}
}
}
:::