/*poj-3468列题, 输入为:
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
10个数,5次操作,Q代表区间为【4,4】的和,C为区间[3,6]区间更新,每个元素都加k*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6;
int c[N];
struct c
{
long long sum;
int dist;
int lazy;
}tree[N];
void build(int l,int r,int node)
{
tree[node].lazy=0;
tree[node].dist=(r-l+1);
if(l==r)
{
tree[node].sum=c[l];
return ;
}
int mid=(l+r)/2;
build(l,mid,node*2);
build(mid+1,r,node*2+1);
tree[node].sum=tree[node*2].sum+tree[node*2+1].sum;
}
void pushdown(int node)
{
if(tree[node].lazy!=0)
{
tree[node*2].lazy+=tree[node].lazy;
tree[node*2+1].lazy+=tree[node].lazy;
tree[node*2].sum+=tree[node].lazy*tree[node*2].dist;
tree[node*2+1].sum+=tree[node].lazy*tree[node*2+1].dist;
tree[node].lazy=0;
}
}
void change(int x,int y,int k,int l,int r,int node)
{
if(x<=l&&y>=r)
{
tree[node].lazy+=k;
tree[node].sum+=tree[node].dist*k;
return ;
}
int mid=(l+r)/2;
pushdown(node);
if(mid>=y)
change(x,y,k,l,mid,node*2);
else if(x>mid)
{
change(x,y,k,mid+1,r,node*2+1);
}
else
{
change(x,y,k,l,mid,node*2);
change(x,y,k,mid+1,r,node*2+1);
}
tree[node].sum=tree[node*2].sum+tree[node*2+1].sum;
}
long long query(int x,int y,int l,int r,int node)
{
if(x<=l&&y>=r)
{
return tree[node].sum;
}
int mid=(l+r)/2;
pushdown(node);
if(mid>=y)
return query( x, y, l, mid, node*2);
else if(mid<x)
return query( x, y, mid+1, r, node*2+1);
else
return query( x, y, l, mid, node*2)+query( x, y, mid+1, r, node*2+1);
}
int main(void)
{
int m,n;
while(scanf("%d %d",&m,&n)!=EOF)
{
memset(c,0,sizeof(c));
memset(tree,0,sizeof(tree));
for(int i=1;i<=m;i++)
{
scanf("%d",&c[i]);
}
build(1,m,1);
char ch;
int a,b;
long long k;
while(n--)
{
getchar();
scanf("%c",&ch);
if(ch=='Q')
{
scanf("%d %d",&a,&b);
printf("%lld\n",query(a,b,1,m,1));
}
else if(ch=='C')
{
scanf("%d %d %lld",&a,&b,&k);
change(a,b,k,1,m,1);
}
}
}
}
acm算法之线段树区间修改(lazy标记)
最新推荐文章于 2024-08-14 11:22:43 发布