【JZOJ4933】C
Description
Solution
一看就是恶心的线段树,首先1~6操作是很经典的线段树维护。
然后看7操作,很显然我们可以对于每一个段维护一个从左边开始的最长子串和数字,从右边开始的,还有就是整段的最长子串和数字,合并的时候分类讨论一下即可(说得轻巧)。
查询的时候也是分类讨论一下即可(呵呵)。
是不是已经感受到代码量的剧增了?
Code
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100010
#define inf 2147483647
#define ll long long
using namespace std;
struct node{
int mx,mi,lz,fz;
ll s;
int fr,frs,en,ens,md,mds;
}tr[N*4];
int a[N];
void put(int v,int l,int r)
{
node tx=tr[v*2],ty=tr[v*2+1];
int mid=(l+r)/2;
if(tr[v].fz)
{
int z=tr[v].fz;
tx.mx=ty.mx=tx.mi=ty.mi=tx.frs=ty.frs=tx.ens=ty.ens=tx.mds=ty.mds=z;
tx.s=(mid-l+1)*1ll*z;
ty.s=(r-mid)*1ll*z;
tx.fr=tx.en=tx.md=mid-l+1;
ty.fr=ty.en=ty.md=r-mid;
tx.fz=ty.fz=z;
tx.lz=ty.lz=0;
tr[v].fz=0;
}
if(tr[v].lz)
{
int z=tr[v].lz;
tx.mx+=z,ty.mx+=z,tx.mi+=z,ty.mi+=z,tx.frs+=z,ty.frs+=z,tx.ens+=z,ty.ens+=z,tx.mds+=z,ty.mds+=z;
tx.s+=(mid-l+1)*1ll*z;
ty.s+=(r-mid)*1ll*z;
tx.lz+=z,ty.lz+=z;
tr[v].lz=0;
}
tr[v*2]=tx,tr[v*2+1]=ty;
}
void update(int v,int l,int r)
{
node tx=tr[v*2],ty=tr[v*2+1];
tr[v].mx=max(tx.mx,ty.mx);
tr[v].mi=min(tx.mi,ty.mi);
tr[v].s=tx.s+ty.s;
tr[v].md=tx.md,tr[v].mds=tx.mds;
if(tr[v].md<ty.md) tr[v].md=ty.md,tr[v].mds=ty.mds;
if(tx.ens==ty.frs)
{
int t=tx.en+ty.fr;
if(tr[v].md<t) tr[v].md=t,tr[v].mds=tx.ens;
}
int mid=(l+r)/2;
int lw=mid-l+1,rw=r-mid;
tr[v].fr=tx.fr,tr[v].frs=tx.frs;
tr[v].en=ty.en,tr[v].ens=ty.ens;
if(tx.fr==lw && tx.frs==ty.frs) tr[v].fr=tx.fr+ty.fr;
if(ty.en==rw && ty.ens==tx.ens) tr[v].en=tx.en+ty.en;
}
int stop=0;
void build(int v,int l,int r)
{
if(l==r)
{
tr[v].mx=tr[v].mi=tr[v].frs=tr[v].ens=tr[v].mds=tr[v].s=a[l];
tr[v].fr=tr[v].en=tr[v].md=1;
return;
}
int mid=(l+r)/2;
build(v*2,l,mid);
build(v*2+1,mid+1,r);
update(v,l,r);
}
void add(int v,int l,int r,int x,int y,int z)
{
if(l==x && r==y)
{
node t=tr[v];
t.mx+=z,t.mi+=z,t.frs+=z,t.ens+=z,t.mds+=z;
t.s+=z*1ll*(r-l+1);
t.lz+=z;
tr[v]=t;
return;
}
put(v,l,r);
int mid=(l+r)/2;
if(y<=mid) add(v*2,l,mid,x,y,z);
else if(x>mid) add(v*2+1,mid+1,r,x,y,z);
else
{
add(v*2,l,mid,x,mid,z);
add(v*2+1,mid+1,r,mid+1,y,z);
}
update(v,l,r);
}
void ffz(int v,int l,int r,int x,int y,int z)
{
if(l==x && r==y)
{
node t=tr[v];
t.mx=t.mi=t.frs=t.ens=t.mds=z;
t.fr=t.en=t.md=r-l+1;
t.s=(r-l+1)*1ll*z;
t.fz=z,t.lz=0;
tr[v]=t;
return;
}
put(v,l,r);
int mid=(l+r)/2;
if(y<=mid) ffz(v*2,l,mid,x,y,z);
else if(x>mid) ffz(v*2+1,mid+1,r,x,y,z);
else
{
ffz(v*2,l,mid,x,mid,z);
ffz(v*2+1,mid+1,r,mid+1,y,z);
}
update(v,l,r);
}
ll qsum(int v,int l,int r,int x,int y)
{
if(l==x && r==y) return tr[v].s;
put(v,l,r);
int mid=(l+r)/2;
if(y<=mid) return qsum(v*2,l,mid,x,y);
else if(x>mid) return qsum(v*2+1,mid+1,r,x,y);
else return qsum(v*2,l,mid,x,mid)+qsum(v*2+1,mid+1,r,mid+1,y);
}
int qmin(int v,int l,int r,int x,int y)
{
if(l==x && r==y) return tr[v].mi;
put(v,l,r);
int mid=(l+r)/2;
if(y<=mid) return qmin(v*2,l,mid,x,y);
else if(x>mid) return qmin(v*2+1,mid+1,r,x,y);
else return min(qmin(v*2,l,mid,x,mid),qmin(v*2+1,mid+1,r,mid+1,y));
}
int qmax(int v,int l,int r,int x,int y)
{
if(l==x && r==y) return tr[v].mx;
put(v,l,r);
int mid=(l+r)/2;
if(y<=mid) return qmax(v*2,l,mid,x,y);
else if(x>mid) return qmax(v*2+1,mid+1,r,x,y);
else return max(qmax(v*2,l,mid,x,mid),qmax(v*2+1,mid+1,r,mid+1,y));
}
int p,cd,o;
void qlen(int v,int l,int r,int x,int y)
{
if(l==x && r==y)
{
o=max(o,tr[v].md);
if(p!=tr[v].frs) p=tr[v].frs,cd=tr[v].fr;
else cd+=tr[v].fr;
o=max(o,cd);
if(tr[v].fr<r-l+1) p=tr[v].ens,cd=tr[v].en;
o=max(o,cd);
return;
}
put(v,l,r);
int mid=(l+r)/2;
if(y<=mid) qlen(v*2,l,mid,x,y);
else if(x>mid) qlen(v*2+1,mid+1,r,x,y);
else
{
qlen(v*2,l,mid,x,mid);
qlen(v*2+1,mid+1,r,mid+1,y);
}
}
int main()
{
int n,q;
scanf("%d %d",&n,&q);
fo(i,1,n) scanf("%d",&a[i]);
build(1,1,n);
while(q--)
{
int t;
scanf("%d",&t);
if(t==1)
{
int l,r,v;
scanf("%d %d %d",&l,&r,&v);
add(1,1,n,l,r,v);
}
else if(t==2)
{
int l,r,v;
scanf("%d %d %d",&l,&r,&v);
add(1,1,n,l,r,-v);
}
else if(t==3)
{
int l,r,v;
scanf("%d %d %d",&l,&r,&v);
ffz(1,1,n,l,r,v);
}
else if(t==4)
{
int l,r;
scanf("%d %d",&l,&r);
printf("%lld\n",qsum(1,1,n,l,r));
}
else if(t==5)
{
int l,r;
scanf("%d %d",&l,&r);
printf("%d\n",qmin(1,1,n,l,r));
}
else if(t==6)
{
int l,r;
scanf("%d %d",&l,&r);
printf("%d\n",qmax(1,1,n,l,r));
}
else if(t==7)
{
int l,r;
scanf("%d %d",&l,&r);
p=-inf,cd=0,o=0;
qlen(1,1,n,l,r);
printf("%d\n",o);
}
}
}