传送门:hihocoder 1080
给定一个长度为n的数组,有两种操作:
(1)对范围[l,r]内的数都加上x(x可为负)
(2)把范围[l,r]内的数都变成x
问每一步操作后整个数组的和为多少
两种更新姿势的线段树,写好对应的更新函数即可
/******************************************************
* File Name: building.cpp
* Author: kojimai
* Create Time: 2014年12月01日 星期一 20时48分38秒
******************************************************/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int FFF = 100005;
struct nodes
{
int l,r,sum,add,change;
}node[FFF<<2];
void build(int l,int r,int num)
{
node[num].l = l; node[num].r = r; node[num].add = 0; node[num].change = 0;
if(l == r)
{
scanf("%d",&node[num].sum);
return;
}
int mid = (l+r) >> 1;
build(l,mid,num<<1);
build(mid+1,r,num<<1|1);
node[num].sum = node[num<<1].sum + node[num<<1|1].sum;
return;
}
void push_change(int num)
{
node[num<<1].change = node[num].change;
node[num<<1].add = 0;
node[num<<1].sum = (node[num<<1].r - node[num<<1].l + 1) * node[num<<1].change;
node[num<<1|1].change = node[num].change;
node[num<<1|1].add = 0;
node[num<<1|1].sum = (node[num<<1|1].r - node[num<<1|1].l + 1) * node[num<<1|1].change;
node[num].change = 0;
}
void push_add(int num)
{
node[num<<1].add += node[num].add;
node[num<<1].sum += (node[num<<1].r - node[num<<1].l + 1) * node[num].add;
node[num<<1|1].add += node[num].add;
node[num<<1|1].sum += (node[num<<1|1].r - node[num<<1|1].l + 1)* node[num].add;
node[num].add = 0;
}
void update1(int l,int r,int z,int num)
{
if(node[num].l == node[num].r)
{
node[num].sum = z;
node[num].add = node[num].change = 0;
return;
}
if(node[num].change)
push_change(num);
if(node[num].add)
push_add(num);
if(node[num].l == l && node[num].r == r)
{
node[num].change = z;
node[num].sum = (r-l+1)*z;
node[num].add = 0;
return;
}
int mid = (node[num].l + node[num].r) >> 1;
if(mid >= r)
update1(l,r,z,num<<1);
else if(mid < l)
update1(l,r,z,num<<1|1);
else
{
update1(l,mid,z,num<<1);
update1(mid+1,r,z,num<<1|1);
}
node[num].sum = node[num<<1].sum + node[num<<1|1].sum;
return;
}
void update0(int l,int r,int z,int num)
{
if(node[num].l == node[num].r)
{
node[num].sum += z;
node[num].add = node[num].change = 0;
//cout<<"num = "<<num<<" nl = "<<node[num].l<<" nr = "<<node[num].r<<" l = "<<l<<" r = "<<r<<" sum = "<<node[num].sum<<endl;
return;
}
if(node[num].change)
push_change(num);
if(node[num].add)
push_add(num);
if(node[num].l == l && node[num].r == r)
{
node[num].change = 0;
node[num].sum += z * (r - l + 1);
node[num].add = z;
//cout<<"num = "<<num<<" nl = "<<node[num].l<<" nr = "<<node[num].r<<" l = "<<l<<" r = "<<r<<" sum = "<<node[num].sum<<endl;
return;
}
int mid = (node[num].l + node[num].r) >> 1;
if(mid >= r)
update0(l,r,z,num<<1);
else if(mid < l)
update0(l,r,z,num<<1|1);
else
{
update0(l,mid,z,num<<1);
update0(mid+1,r,z,num<<1|1);
}
node[num].sum = node[num<<1].sum + node[num<<1|1].sum;
//cout<<"num = "<<num<<" nl = "<<node[num].l<<" nr = "<<node[num].r<<" l = "<<l<<" r = "<<r<<" sum = "<<node[num].sum<<endl;
return;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
build(1,n+1,1);
int type,x,y,z;
while(m--)
{
scanf("%d%d%d%d",&type,&x,&y,&z);
if(type == 1)
update1(x+1,y+1,z,1);
else
update0(x+1,y+1,z,1);
printf("%d\n",node[1].sum);
}
return 0;
}