A Simple Problem with Integers | ||||||
| ||||||
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 | ||||||
Input contain multiple test cases,for each case: The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. | ||||||
Output | ||||||
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. | ||||||
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 | ||||||
Source | ||||||
POJ Monthly--2007.11.25, Yang Yi | ||||||
Recommend | ||||||
`Wind @Hrbust |
就是个简单的区间更新值的题目,一下子学到了很多东西,还是自己的模板不够好:这里对应AC代码强调几个小小的细节:
#include<stdio.h>
#include<string.h>
using namespace std;
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
#define ll long long int
ll tree[1212112];
ll flag[1212112];
void pushdown(int l,int r,int rt)//向下维护树内数据
{
if(flag[rt])//如果贪婪标记不是0(说明需要向下进行覆盖区间(或点)的值)
{
int m=(l+r)/2;
flag[rt*2]+=flag[rt];//千万记住,这里要写+=,否则会WA。(有可能一下子多次C操作。)
flag[rt*2+1]+=flag[rt];
tree[rt*2]+=(m-l+1)*flag[rt];//千万理解如何覆盖的区间值(对应线段树的图片理解(m-l)+1)是什么意识.
tree[rt*2+1]+=(r-(m+1)+1)*flag[rt];
flag[rt]=0;
}
}
void pushup(int rt)
{
tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}
void build( int l ,int r , int rt )
{
if( l == r )
{
scanf("%lld",&tree[rt]);
return ;
}
else
{
int m = (l+r)>>1 ;
build(lson) ;
build(rson) ;
pushup(rt) ;
return ;
}
}
ll Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return tree[rt];
}
else
{
pushdown(l,r,rt);//查询区间的时候也别忘记pushdown,否则数据会对不上
int m=(l+r)>>1;
ll ans=0;
if(L<=m)
{
ans+=Query(L,R,lson);
}
if(m<R)
{
ans+=Query(L,R,rson);
}
return ans;
}
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)//覆盖的是区间~
{
tree[rt]+=c*((r-l)+1);//覆盖当前点的值
flag[rt]+=c;//同时懒惰标记~!(同样是+=)
return ;
}
pushdown(l,r,rt);
int m=(l+r)/2;
if(L<=m)
{
update(L,R,c,lson);
}
if(m<R)
{
update(L,R,c,rson);
}
pushup(rt);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(flag,0,sizeof(flag));
memset(tree,0,sizeof(tree));
build(1,n,1);
for(int i=0;i<m;i++)
{
char s[5];
int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[0]=='Q')
{
printf("%lld\n",Query(x,y,1,n,1));
}
if(s[0]=='C')
{
ll c;
scanf("%lld",&c);
update(x,y,c,1,n,1);
}
}
}
}