Description
一行N个方格,开始每个格子里的数都是0。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N≤100000,提问和修改的总数可能达到100000条。
Input
第一行,
n
n
n,为方格个数
第二行,
m
m
m,为操作数
第
3
3
3到
m
+
2
m+2
m+2行
每行第一个字符,
M
M
M或
C
C
C
如果是
M
M
M,后面有
l
l
l,
k
k
k
为在
l
l
l点加
k
k
k
如果是
C
C
C,后面有
l
l
l,
r
r
r
为输出
l
l
l,
r
r
r之间数的和
Output
若干行
每行一个数
为
l
i
l_i
li,
r
i
r_i
ri之间数的和
Sample Input
20
6
M 1 1
M 2 2
M 3 4
M 3 -5
M 6 7
C 2 6
Sample Output
8
思路
线段树
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
struct tree_1
{
ll l,r,k,store;
}Tree[400250];
int A[100250];
int Operation,Sum;
int n,m,k;
//--------------------------------------------------------------
void Go(int Hi,int Len)
{
if(!Tree[Hi].store)return;
Tree[Hi*2].store+=Tree[Hi].store;
Tree[Hi*2+1].store+=Tree[Hi].store;
Tree[Hi*2].k+=Tree[Hi].store*(Len-Len/2);
Tree[Hi*2+1].k+=Tree[Hi].store*(Len/2);
Tree[Hi].store=0;
}
void Tree_Buil(int Hi,int l,int r)
{
Tree[Hi].l=l;Tree[Hi].r=r;
if(l==r)Tree[Hi].k=A[l];
else
{
int Mid=(l+r)/2;
Tree_Buil(Hi*2,l,Mid);
Tree_Buil(Hi*2+1,Mid+1,r);
Tree[Hi].k=Tree[Hi*2].k+Tree[Hi*2+1].k;
}
return;
}
//--------------------------------------------------------------
void Add(int Hi,int l,int r,int k)
{
if(Tree[Hi].l==l && Tree[Hi].r==r)
{
Tree[Hi].k+=(r-l+1)*k;
Tree[Hi].store+=k;
return;
}
if(Tree[Hi].l==Tree[Hi].r)return;
Go(Hi,Tree[Hi].r-Tree[Hi].l+1);
int Mid=(Tree[Hi].l+Tree[Hi].r)/2;
if(l<=r && r<=Mid)Add(Hi*2,l,r,k);
else if(l>Mid && l<=r)Add(Hi*2+1,l,r,k);
else
{
if(l<=Mid)Add(Hi*2,l,Mid,k);
if(r>Mid)Add(Hi*2+1,Mid+1,r,k);
}
Tree[Hi].k=Tree[Hi*2].k+Tree[Hi*2+1].k;
}
//--------------------------------------------------------------
ll Num(int Hi,int l,int r)
{
// printf("%d %lld\n",Hi,Tree[Hi].k);
if(Tree[Hi].l==l && Tree[Hi].r==r)
return Tree[Hi].k;
Go(Hi,Tree[Hi].r-Tree[Hi].l+1);
int Mid=(Tree[Hi].l+Tree[Hi].r)/2;
ll Ans=0;
if(l<=r && r<=Mid)Ans+=Num(Hi*2,l,r);
else if(l>Mid && l<=r)Ans+=Num(Hi*2+1,l,r);
else
{
if(l<=Mid)Ans+=Num(Hi*2,l,Mid);
if(r>Mid)Ans+=Num(Hi*2+1,Mid+1,r);
}
return Ans;
}
//--------------------------------------------------------------
int main()
{
Sum=0;
scanf("%d%d",&n,&m);
getchar();
Tree_Buil(1,1,n);
for(int i=1;i<=m;++i)
{
int l,r;
Operation=getchar();
if(Operation=='M')
{
scanf("%d%d",&l,&k);
getchar();
Add(1,l,l,k);
}
if(Operation=='C')
{
scanf("%d%d",&l,&r);
getchar();
printf("%lld\n",Num(1,l,r));
}
}
return 0;
}