您的位置:首页 > 其它

A Simple Problem with Integers_poj3468_线段树

2016-11-23 20:37 483 查看

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.

Analysis

一直只知道线段树如何单点操作,后来才发现有区间操作的精髓被我遗弃了。今天补上

关于lazyTag

延迟标记,当我们需要对某一区间连续修改时,我们可以先不管他,用一个下标lazy记录对应区间修改,遇到查询问题的时候往下传递lazy,这样就能保证修改和查询的复杂度是logn的

这题是很裸的区间修改查询,树状数组也能做,就当练手吧

Code

#include <stdio.h>
#define N 100001
#define ll __int64
using namespace std;
struct tree{int l,r;ll lazy,sum;}t[N<<2+1];
void build(int f,int x,int y)
{
t[f].l=x;t[f].r=y;
if (x==y)
{
scanf("%I64d",&t[f].sum);
return;
}
int mid=(x+y)>>1;
build(f*2,x,mid);
build(f*2+1,mid+1,y);
t[f].sum=t[f*2].sum+t[f*2+1].sum;
}
void pushDown(int f,int len)
{
t[f*2].lazy+=t[f].lazy;
t[f*2+1].lazy+=t[f].lazy;
t[f*2].sum+=t[f].lazy*(len-len/2);
t[f*2+1].sum+=t[f].lazy*(len/2);
t[f].lazy=0;
}
void modify(int f,int x,int y,ll v)
{
if (x<=t[f].l&&y>=t[f].r)
{
t[f].lazy+=v;
t[f].sum+=(t[f].r-t[f].l+1)*v;
return;
}
if (t[f].lazy)
pushDown(f,t[f].r-t[f].l+1);
int mid=(t[f].l+t[f].r)>>1;
if (y<=mid)
modify(f*2,x,y,v);
else
if (x>mid)
modify(f*2+1,x,y,v);
else
modify(f*2,x,mid,v),modify(f*2+1,mid+1,y,v);
t[f].sum=t[f*2].sum+t[f*2+1].sum;
}
ll query(int f,int x,int y)
{
if (x<=t[f].l&&y>=t[f].r)
return t[f].sum;
if (t[f].lazy)
pushDown(f,t[f].r-t[f].l+1);
int mid=(t[f].l+t[f].r)>>1;
if (y<=mid)
return query(f*2,x,y);
else
if (x>mid)
return query(f+f+1,x,y);
else
return query(f+f,x,mid)+query(f+f+1,mid+1,y);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
build(1,1,n);
for (int i=1;i<=m;i++)
{
int x,y;
char opt;
ll v;
getchar();
scanf("%c%d%d",&opt,&x,&y);
if (opt=='C')
{
scanf("%I64d",&v);
modify(1,x,y,v);
}
else
printf("%I64d\n",query(1,x,y));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: