http://poj.org/problem?id=3468线段数的构造,查询,修改!
struct node{
int l,r,m;
long long sum;//当前区间的和
long long add;//区间需要加上的数值
}
题意:
给定n个数字A1,A2,..,An,Q个操作。
C x y z,把区间x y内的数都加上z
Q x y,求区间x y内所有数的和。
总结:
基础代码一定要对,调试了半天,最后发现是swap(x,y,t)写错了!!!!
WA了一次,数据是long long才行,要分析清楚数据范围!!!
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cassert>
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <algorithm>
#define min(x,y) (x<y?x:y)
#define max(x,y) (x>y?x:y)
#define swap(x,y,t) (t=x,x=y,y=t)
#define clr(list) memset(list,0,sizeof(list))
#define LL long long
#define maxn 200005
using namespace std;
struct node{
int l,r,m;
LL sum;
LL add;
} tree[2*maxn];
int a[maxn];
LL build(int l,int r,int root)
{
tree[root].l=l;
tree[root].r=r;
tree[root].m=(l+r)/2;
tree[root].add=0;
if (l==r)
{
tree[root].sum=a[l];
return tree[root].sum;
}
long long sum_l=build(l,(l+r)/2,root*2);
long long sum_r=build((l+r)/2+1,r,root*2+1);
tree[root].sum=sum_l+sum_r;
return tree[root].sum;
}
int insert(int l,int r,int add,int root)
{
if (l<=tree[root].l && r>=tree[root].r)
{
tree[root].add+=add;
tree[root].sum+=add * (tree[root].r-tree[root].l+1);
return 0;
}
if (tree[root].add) //向下更新
{
tree[2*root].sum+=tree[root].add * (tree[root*2].r-tree[root*2].l+1);
tree[2*root].add+=tree[root].add;
tree[2*root+1].sum+=tree[root].add * (tree[root*2+1].r-tree[root*2+1].l+1);
tree[2*root+1].add+=tree[root].add;
tree[root].add=0;
}
if (l<=tree[root].m)
insert(l,r,add,root*2);
if (r>tree[root].m)
insert(l,r,add,root*2+1);
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum; //这里回溯啊
return 0;
}
LL search(int l,int r,int root)
{
if (l<=tree[root].l && r>=tree[root].r)
return tree[root].sum;
if (tree[root].add) //向下更新
{
tree[2*root].sum+=tree[root].add * (tree[root*2].r-tree[root*2].l+1);
tree[2*root].add+=tree[root].add;
tree[2*root+1].sum+=tree[root].add * (tree[root*2+1].r-tree[root*2+1].l+1);
tree[2*root+1].add+=tree[root].add;
tree[root].add=0;
}
LL sum_l=0,sum_r=0;
if (l<=tree[root].m)
sum_l=search(l,r,2*root);
if (r>tree[root].m)
sum_r=search(l,r,2*root+1);
return sum_l+sum_r;
}
int main()
{
int n,m;
int x,y,z;
int tmp;
char ch;
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1);
for (int i=1;i<=m;i++)
{
scanf("\n%c",&ch);
if (ch=='C')
{
scanf("%d%d%d",&x,&y,&z);
if (x>y)
swap(x,y,tmp);
insert(x,y,z,1);
}
else
{
scanf("%d%d",&x,&y);
if (x>y)
swap(x,y,tmp);
printf("%I64d\n",search(x,y,1));
}
}
return 0;
}