线段树,维护一个add域和lazy
2672ms
也可以用树状数组来做:http://kenby.iteye.com/blog/962159
这里给出线段树代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
#define N 100005
typedef long long ll;
struct node{
int l, r;
ll sum;
ll add;
bool lazy;
}Tree[N * 5];
int a[N];
ll build(int l, int r, int x)
{
Tree[x].l = l;
Tree[x].r = r;
Tree[x].add = 0;
Tree[x].lazy = 0;
if (l == r)
{
Tree[x].sum = a[Tree[x].l];
return Tree[x].sum;
}
int mid = (l + r) / 2;
Tree[x].sum = build(l, mid, x * 2) + build(mid + 1, r, x * 2 + 1);
return Tree[x].sum;
}
void push_down(int x)
{
Tree[x * 2].add += Tree[x].add;
Tree[x * 2 + 1].add += Tree[x].add;
Tree[x].sum += Tree[x].add * (Tree[x].r - Tree[x].l + 1);
Tree[x].lazy = 0;
Tree[x].add = 0;
Tree[x * 2].lazy = 1;
Tree[x * 2 + 1].lazy = 1;
}
void update(int l, int r, int val, int x)
{
if ((Tree[x].l == l && Tree[x].r == r))
{
Tree[x].lazy = 1;
Tree[x].add += val;
return ;
}
if (Tree[x].lazy == 1)
push_down(x);
int mid = (Tree[x].l + Tree[x].r) / 2;
if (mid < l)update(l, r, val, x * 2 + 1);
else if (mid >= r)update(l, r, val, x * 2);
else {
update(l, mid, val, x * 2);
update(mid + 1, r, val, x * 2 + 1);
}
Tree[x].sum += (val * (r - l + 1));
}
ll find(int l, int r, int x)
{
if (l == Tree[x].l && r == Tree[x].r )
{
return (r - l + 1) * Tree[x].add + Tree[x].sum;
}
ll ans = 0;
if (Tree[x].lazy)
{
ans += (Tree[x].add) * ( r - l + 1);
}
int mid = (Tree[x].l + Tree[x].r) / 2;
if (mid < l) ans += find(l, r, x * 2 + 1);
else if (mid >= r) ans += find(l, r, x * 2);
else {
ans += (find(l, mid, x * 2) + find(mid + 1, r, x * 2 + 1)) ;
}
return ans;
}
int main()
{
int n, q;
// FILE* fp = fopen("in.txt", "r");
// FILE* ff = fopen("out.txt", "w");
scanf("%d %d", &n, &q);
for (int i = 1; i <= n; i++)
scanf( "%d", a + i);
build(1, n, 1);
char op[3];
int a, b, c;
for (int i = 0; i < q; i++)
{
scanf( "%s %d %d", op, &a, &b);
if (op[0] == 'C')
{
scanf( "%d", &c);
update(a, b, c, 1);
}
else
{
//fprintf(ff, "%intd\n", find(a, b, 1));
printf( "%lld\n", find(a, b, 1));
}
}
// getchar();
return 0;
}