- 题意(原题):
- 数列,五种操作,元素与操作个数都是10w。操作为区间加法,区间设为一个值,求区间和,区间最大值区间最小值。
- 思路:
- 维护两个lazy,一个add一个set,两个lazy不能共存。
- 代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
#define MAXN (110000)
#define inf ((LL)999999999999999999)
using namespace std
struct node
{
int l,r,mid,ls,rs
LL sumVal,minVal,maxVal,setLazy,addLazy
node()
{
l=r=ls=rs=0
sumVal=minVal=maxVal=addLazy=0
setLazy=-inf
}
}a[MAXN*2]
//setLazyÓëaddLazy²»¹²´æ
char ss[11]
int len=0,n,m
LL readVal[MAXN]
//ÕâÁ½¸öº¯ÊýÖ»¹Ü×Ô¼ºÕâ¸öµã
void treeSetLazy(int x,LL val)
{
a[x].setLazy=val
a[x].addLazy=0
a[x].sumVal=val*(a[x].r-a[x].l+1)
a[x].minVal=val
a[x].maxVal=val
return
}
void treeAddLazy(int x,LL val)
{
if(a[x].setLazy!=-inf)
{
treeSetLazy(x,a[x].setLazy+val)
return
}
a[x].addLazy+=val
a[x].sumVal+=val*(a[x].r-a[x].l+1)
a[x].minVal+=val
a[x].maxVal+=val
return
}
void treeUpdate(int x)
{
if(a[x].l==a[x].r)
{
a[x].minVal=a[x].sumVal
a[x].maxVal=a[x].sumVal
return
}
a[x].sumVal=a[a[x].ls].sumVal+a[a[x].rs].sumVal
a[x].minVal=min(a[a[x].ls].minVal,a[a[x].rs].minVal)
a[x].maxVal=max(a[a[x].ls].maxVal,a[a[x].rs].maxVal)
return
}
void treeBuild(int l,int r)
{
int now=++len
a[now].l=l
if(a[now].l==a[now].r)
{
a[now].sumVal=readVal[l]
a[now].minVal=readVal[l]
a[now].maxVal=readVal[l]
return
}
a[now].ls=len+1
treeBuild(l,a[now].mid)
a[now].rs=len+1
treeBuild(a[now].mid+1,r)
treeUpdate(now)
return
}
void treeAdd(int x,int l,int r,int val)
{
if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r))
{
treeAddLazy(x,val)
return
}
if(a[x].setLazy!=-inf)
{
treeSetLazy(a[x].ls,a[x].setLazy)
treeSetLazy(a[x].rs,a[x].setLazy)
a[x].setLazy=-inf
}
if(a[x].addLazy)
{
treeAddLazy(a[x].ls,a[x].addLazy)
treeAddLazy(a[x].rs,a[x].addLazy)
a[x].addLazy=0
}
if(l<=a[x].mid)treeAdd(a[x].ls,l,min(a[x].mid,r),val)
if(r>=a[x].mid+1)treeAdd(a[x].rs,max(a[x].mid+1,l),r,val)
treeUpdate(x)
return
}
void treeSet(int x,int l,int r,int val)
{
if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r))
{
treeSetLazy(x,val)
return
}
if(a[x].setLazy!=-inf)
{
treeSetLazy(a[x].ls,a[x].setLazy)
treeSetLazy(a[x].rs,a[x].setLazy)
a[x].setLazy=-inf
}
if(a[x].addLazy)
{
treeAddLazy(a[x].ls,a[x].addLazy)
treeAddLazy(a[x].rs,a[x].addLazy)
a[x].addLazy=0
}
if(l<=a[x].mid)treeSet(a[x].ls,l,min(a[x].mid,r),val)
if(r>=a[x].mid+1)treeSet(a[x].rs,max(a[x].mid+1,l),r,val)
treeUpdate(x)
return
}
LL treeGetSum(int x,int l,int r)
{
if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r))
{
return a[x].sumVal
}
if(a[x].setLazy!=-inf)
{
return a[x].setLazy*(LL)(r-l+1)
}
if(a[x].addLazy)
{
treeAddLazy(a[x].ls,a[x].addLazy)
treeAddLazy(a[x].rs,a[x].addLazy)
a[x].addLazy=0
}
LL ans=0
if(l<=a[x].mid)ans+=treeGetSum(a[x].ls,l,min(a[x].mid,r))
if(r>=a[x].mid+1)ans+=treeGetSum(a[x].rs,max(a[x].mid+1,l),r)
return ans
}
LL treeGetMax(int x,int l,int r)
{
if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r)||(a[x].setLazy!=-inf))
{
return a[x].maxVal
}
if(a[x].setLazy!=-inf)
{
treeSetLazy(a[x].ls,a[x].setLazy)
treeSetLazy(a[x].rs,a[x].setLazy)
a[x].setLazy=-inf
}
if(a[x].addLazy)
{
treeAddLazy(a[x].ls,a[x].addLazy)
treeAddLazy(a[x].rs,a[x].addLazy)
a[x].addLazy=0
}
LL ans=-inf
if(l<=a[x].mid)ans=max(ans,treeGetMax(a[x].ls,l,min(a[x].mid,r)))
if(r>=a[x].mid+1)ans=max(ans,treeGetMax(a[x].rs,max(a[x].mid+1,l),r))
return ans
}
LL treeGetMin(int x,int l,int r)
{
if(a[x].l==a[x].r||(a[x].l==l&&a[x].r==r)||(a[x].setLazy!=-inf))
{
return a[x].minVal
}
if(a[x].setLazy!=-inf)
{
treeSetLazy(a[x].ls,a[x].setLazy)
treeSetLazy(a[x].rs,a[x].setLazy)
a[x].setLazy=-inf
}
if(a[x].addLazy)
{
treeAddLazy(a[x].ls,a[x].addLazy)
treeAddLazy(a[x].rs,a[x].addLazy)
a[x].addLazy=0
}
LL ans=inf
if(l<=a[x].mid)ans=min(ans,treeGetMin(a[x].ls,l,min(a[x].mid,r)))
if(r>=a[x].mid+1)ans=min(ans,treeGetMin(a[x].rs,max(a[x].mid+1,l),r))
return ans
}
int main()
{
scanf("%d%d",&n,&m)
for(int i=1
treeBuild(1,n)
while(m--)
{
int x,y,z
scanf("%s",ss+1)
if(ss[2]=='d')
{
scanf("%d%d%d",&x,&y,&z)
treeAdd(1,x,y,z)
}
if(ss[2]=='e')
{
scanf("%d%d%d",&x,&y,&z)
treeSet(1,x,y,z)
}
if(ss[2]=='u')
{
scanf("%d%d",&x,&y)
printf("%lld\n",treeGetSum(1,x,y))
}
if(ss[2]=='a')
{
scanf("%d%d",&x,&y)
printf("%lld\n",treeGetMax(1,x,y))
}
if(ss[2]=='i')
{
scanf("%d%d",&x,&y)
printf("%lld\n",treeGetMin(1,x,y))
}
}
return 0
}