D - A Simple Problem with Integers
Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u
Submit
Status
Practice
POJ 3468
Description
给出了一个序列,你需要处理如下两种询问。
“C a b c”表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
“Q a b” 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
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
两周前写过这题,当时代码lu的行,今天看不下去了,重新写一遍
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string.h>
using namespace std;
//线段树
//插线问线
//Lazy更新
//重新写
const int maxn=100005;
long long int sum[maxn<<2];
long long int Lazy[maxn<<2];
long long int N;
long long int Q;
void Push_Up(int root)
{
sum[root]=sum[root<<1]+sum[root<<1|1];
}
void Push_Down(int root,int len)
{
if(Lazy[root])
{
Lazy[root<<1]+=Lazy[root];
Lazy[root<<1|1]+=Lazy[root];
sum[root<<1]+=Lazy[root]*(len-(len>>1));
sum[root<<1|1]+=Lazy[root]*(len>>1);
Lazy[root]=0;
}
}
void Build(int root,int left,int right)
{
Lazy[root]=0;
if(left==right)
{
scanf("%I64d",&sum[root]);
return;
}
int mid=(left+right)>>1;
Build(root<<1,left,mid);
Build(root<<1|1,mid+1,right);
Push_Up(root);
}
void Update(int root,int left,int right,int find_left,int find_right,int add_num)
{
if(left>=find_left&&right<=find_right)
{
Lazy[root]+=add_num;
sum[root]+=add_num*(right-left+1);
return;
}
Push_Down(root,right-left+1);//下沉数据
int mid=(left+right)>>1;
if(find_right<=mid)
Update(root<<1,left,mid,find_left,find_right,add_num);
else if(find_left>mid)
Update(root<<1|1,mid+1,right,find_left,find_right,add_num);
else
{
Update(root<<1,left,mid,find_left,mid,add_num);
Update(root<<1|1,mid+1,right,mid+1,find_right,add_num);
}
Push_Up(root);//最后还要上浮数据
}
long long int Query(int root,int left,int right,int find_left,int find_right)
{
if(left>=find_left&&right<=find_right)
return sum[root];
Push_Down(root,right-left+1);//每次都要更新到查询区间的下一层
int mid=(left+right)>>1;
if(find_right<=mid)
return Query(root<<1,left,mid,find_left,find_right);
else if(find_left>mid)
return Query(root<<1|1,mid+1,right,find_left,find_right);
else
return Query(root<<1,left,mid,find_left,mid)+Query(root<<1|1,mid+1,right,mid+1,find_right);
}
int main()
{
scanf("%I64d%I64d",&N,&Q);
Build(1,1,N);
while(Q--)
{
char str[2];
int A,B,C;
scanf("%s",str);
if(str[0]=='Q')//查询
{
scanf("%d%d",&A,&B);
printf("%I64d\n",Query(1,1,N,A,B));
}
else if(str[0]=='C')//更新
{
scanf("%d%d%d",&A,&B,&C);
Update(1,1,N,A,B,C);
}
}
return 0;
}