bzoj 3212 线段树模板题
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3212
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
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
55
9
15
HINT
The sums may exceed the range of 32-bit integers.
这是bzoj中难得的模板题~~~~~
#include<cstdio>
#include<iostream>
#define MAXN 800010
using namespace std;
char op[10];int n,m;
struct Segtree{
#define lc(x) x<<1
#define rc(x) ((x<<1)|1)
int l[MAXN],r[MAXN];
long long add[MAXN],s[MAXN];
void update(int x)
{
s[x]=s[lc(x)]+s[rc(x)];
}
void push(int x)
{
s[lc(x)]+=add[x]*(r[lc(x)]-l[lc(x)]+1);
s[rc(x)]+=add[x]*(r[rc(x)]-l[rc(x)]+1);
add[lc(x)]+=add[x];
add[rc(x)]+=add[x];
add[x]=0;
}
long long query(int x,int L,int R)
{
push(x);
if(l[x]>R||r[x]<L)
return 0;
if(l[x]>=L&&r[x]<=R)
return s[x];
return query(lc(x),L,R)+query(rc(x),L,R);
}
void change(int x,int L,int R,int v)
{
push(x);
if(l[x]>R||r[x]<L)
return ;
if(l[x]>=L&&r[x]<=R)
{
s[x]+=v*(r[x]-l[x]+1);
add[x]=v;
return ;
}
change(lc(x),L,R,v);
change(rc(x),L,R,v);
update(x);
}
void build(int x,int L,int R)
{
l[x]=L,r[x]=R,add[x]=0;
if(L==R)
{
scanf("%lld",&s[x]);
return ;
}
int mid=(L+R)/2;
build(lc(x),L,mid);
build(rc(x),mid+1,R);
update(x);
}
}seg;
int main()
{
scanf("%d%d",&n,&m);
seg.build(1,1,n);
while(m--)
{
scanf("%s",op);
if(op[0]=='C')
{
int l,r;long long v;
scanf("%d%d%lld",&l,&r,&v);
seg.change(1,l,r,v);
}
else
{
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",seg.query(1,l,r));
}
}
return 0;
}

本文介绍了一道经典的线段树模板题BZOJ3212,通过给出完整的C++代码实现,展示了如何处理区间加法及区间求和操作,适合初学者学习线段树数据结构。
433

被折叠的 条评论
为什么被折叠?



