https://vjudge.net/problem/UESTC-1057
区间修改,一个个改复杂度是nlogn还不如暴力,这里用到线段树的lazy思想,保证复杂度为logn
#include <iostream>
#include <cstdio>
#include <cstring>
#define lid (id << 1)
#define rid (id << 1 | 1)
using namespace std;
const int maxn = 1e5+6;
int n,a[maxn],q;
struct node
{
int l,r;
long long sum,Max,lazy;
void updata(long long x)
{
sum =sum+(r-l+1)*x; //增加
Max=Max+x;
lazy=lazy+x;
/* sum = (r-l+1)*x; //修改
Max=x;
lazy=x; */
}
} tr[maxn*4];
void push_up(int id)
{
tr[id].sum=tr[lid].sum+tr[rid].sum;
tr[id].Max = max(tr[lid].Max,tr[rid].Max);
}
void push_down(int id)
{
int lazyvalue=tr[id].lazy;
if(lazyvalue)
{
tr[lid].updata(lazyvalue);
tr[rid].updata(lazyvalue);
tr[id].lazy=0;
}
}
void build(int id,int l,int r)
{
tr[id].l=l,tr[id].r=r;
tr[id].sum=0,tr[id].Max=0,tr[id].lazy=0;
if(l==r) tr[id].sum=a[l],tr[id].Max=a[l];
else
{
int mid=(l+r)/2;
build(lid,l,mid);
build(rid,mid+1,r);
push_up(id);
}
}
void updata(int id,int l,int r,long long val)
{
if(l==tr[id].l&&tr[id].r==r) tr[id].updata(val);
else
{
push_down(id);
int mid = (tr[id].l+tr[id].r)>>1;
if(r<=mid) updata(lid,l,r,val);
else if (l>mid) updata(rid,l,r,val);
else
{
updata(lid,l,mid,val);
updata(rid,mid+1,r,val);
}
push_up(id);
}
}
long long query_sum(int id,int l,int r)
{
if(l==tr[id].l&&tr[id].r==r) return tr[id].sum;
else
{
push_down(id);
int mid = (tr[id].l+tr[id].r)/2;
if(r<=mid) return query_sum(lid,l,r);
else if(l>mid) return query_sum(rid,l,r);
else return query_sum(lid,l,mid)+query_sum(rid,mid+1,r);
push_up(id);
}
}
long long query_max(int id,int l,int r)
{
if(l==tr[id].l&&tr[id].r==r) return tr[id].Max;
else
{
push_down(id);
int mid = (tr[id].l+tr[id].r)/2;
if(r<=mid) return query_max(lid,l,r);
else if(l>mid) return query_max(rid,l,r);
else return max(query_max(lid,l,mid),query_max(rid,mid+1,r));
push_up(id);
}
}
int main()
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
build(1,1,n);
scanf("%d",&q);
for(int i=1; i<=q; i++)
{
int l,r,val;
scanf("%d%d%d",&l,&r,&val);
updata(1,l,r,val);
printf("%lld\n",query_sum(1,l,r));
}
return 0;
}