Description
You have N integers, A1, A2, … , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, … , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
“C a b c” means adding c to each of Aa, Aa+1, … , Ab. -10000 ≤ c ≤ 10000.
“Q a b” means querying the sum of Aa, Aa+1, … , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
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
Sample Output
4
55
9
15
线段树入门:主要是lazy-tag的方法
#include<stdio.h>
typedef long long ll;
const ll maxn = 100007;
ll tree[4 * 100007 ], add[4 * 100007];
ll a[100007];
void Build_tree(int start,int end,int u)
{
if(start==end)
{
tree[u] = a[end];
return;
}
Build_tree(start, (start + end) / 2, u * 2);//构造左子树
Build_tree((start + end) / 2 + 1, end, u * 2 + 1);//构造右子树
tree[u] = tree[u * 2] + tree[u * 2+1];
}
//lazy-tag方法
void push_down(int u,int m)
{
if(add[u])
{
add[u<<1] += add[u];//
add[ u<<1 | 1 ] += add[u];//
tree[u << 1] += (m - (m >> 1)) * add[u];//
tree[u << 1 | 1] += (m >> 1) * add[u];
add[u] = 0;//取消本层标记
}
}
void update(int L,int R,ll c,int u,int start,int end)//在区间L到R+c
{
if(L<=start&&R>=end)
{
tree[u] += (end - start + 1) * c;//树的区间
add[u] += c;
return;
}
push_down(u, end - start + 1);//向下更新
int mid = (start + end) >> 1;
if(L<=mid)
update(L, R, c, u * 2, start, mid);
if(R>mid)
update(L, R, c, u * 2 + 1, mid + 1, end);
tree[u] = tree[u * 2] + tree[u * 2 + 1];
}
ll querry(int a, int b, int l, int r, int u)
{
//printf("l=%d r=%d u=%d\n", l, r,u);
if(a<=l&&b>=r)
return tree[u];
push_down(u, r - l + 1);
int mid = (l + r) >> 1;
ll ans = 0;
if(a<=mid)
ans += querry(a, b, l, mid, u * 2);
if(b>mid)
ans += querry(a, b, mid + 1, r, u * 2 + 1);
return ans;
}
int main()
{
freopen("11.txt", "r", stdin);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1;i<=n;i++)
scanf("%lld", &a[i]);
Build_tree(1, n, 1);
// for (int i = 1;i<30;i++)
// printf("%d %lld\n",i, tree[i]);建树没有问题
char s[2];
while(m--)
{
scanf("%s", s);
int a, b;
if(s[0]=='C')
{
ll c;
scanf("%d%d%lld", &a, &b, &c);
update(a, b, c, 1, 1, n);
}
else
{
scanf("%d%d", &a, &b);
printf("%lld\n", querry(a, b, 1, n, 1));
}
}
return 0;
}