POJ-3468-A Simple Problem with Integers(线段树区间维护 重写Lazy)

来源:互联网 发布:蒂灵沙在淘宝怎么买 编辑:程序博客网 时间:2024/05/17 04:11

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;}
0 0
原创粉丝点击