题目哈。。http://poj.org/problem?id=3468
最近在队里的寒假作业中第一次遇到了线段树的题,之前也听思雨姐姐说过也看过她写过,但自己始终没个影响,然后自己做了几天也算刚入这个门,会写一些比较基础的线段树了,之所以把这道题写下来是因为线段树的精华还是在于区间修改,也是最实用的部分。
线段树的区间修改,最巧妙的部分是建立一个lazy树,与各个点相对应不用再一一处理而是先输出等后面遇到再加上(个人理解),lazy就是懒的意思,其实也就是个标记,标记如果有值加上就可以。这个时候就需要一个pushdown的操作就可以了。
还有个技巧 我们平常用乘二除二都是*2 /2 大神们更习惯<<2 >>2 据说因为更靠近机器语言所以更快,在以后的刷题生活中也要自己慢慢习惯这种写法
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int manx=100000+200;
long long tree[manx*4];
long long laze[manx*4];
void pushup(long long node)
{
tree[node]=tree[node*2]+tree[node*2+1];
}
void pushdown(long long node,long long k)
{
if(laze[node]!=0)
{
tree[node*2]+=laze[node]*(k-(k/2));
tree[node*2+1]+=laze[node]*(k/2);
laze[node*2]+=laze[node];
laze[node*2+1]+=laze[node];
laze[node]=0;
}
}
void build(long long node,long long begin,long long end)
{
if(begin==end)
{
scanf("%I64d",&tree[node]);
return;
}
int mid=(begin+end)/2;
build(node*2,begin,mid);
build(node*2+1,mid+1,end);
pushup(node);
return;
}
long long query(long long node,long long begin,long long end,long long left,long right)
{
if(begin>=left&&right>=end)
{
return tree[node];
}
pushdown(node,end-begin+1);
long long ans=0,mid=(begin+end)/2;
if(mid>=left)
ans+=query(node*2,begin,mid,left,right);
if(right>mid)
ans+=query(node*2+1,mid+1,end,left,right);
return ans;
}
void update(long long node,long long begin,long long end,long long left,long long right,long long t)
{
if(begin>=left&&right>=end)
{
tree[node]+=(end-begin+1)*t;
laze[node]+=t;
return;
}
pushdown(node,end-begin+1);
long long mid=(begin+end)/2;
if(mid>=left)
update(node*2,begin,mid,left,right,t);
if(right>mid)
update(node*2+1,mid+1,end,left,right,t);
pushup(node);
}
int main()
{
long long n,q;
char s[3];
scanf("%I64d%I64d",&n,&q);
memset(tree,0,sizeof(tree));
memset(laze,0,sizeof(laze));
build(1,1,n);
while(q--)
{
long long a,b,c;
scanf(" %s",s);
if(s[0]=='C')
{
scanf("%I64d%I64d%I64d",&a,&b,&c);
update(1,1,n,a,b,c);
}
else
{
scanf("%I64d%I64d",&a,&b);
printf("%I64d\n",query(1,1,n,a,b));
}
}
return 0;
}