zoukankan      html  css  js  c++  java
  • POJ 3468 线段树 成段更新 懒惰标记

    A Simple Problem with Integers

    Time Limit:5000MS   Memory Limit:131072K
    Case Time Limit:2000MS

    Description

    You have N integers, A1A2, ... , 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 A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of AaAa+1, ... , Ab.

    Output

    You need to answer all Q commands in order. One answer in a line.

    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

    Hint

    The sums may exceed the range of 32-bit integers.
     
    题解:本题也是线段树系列的模板题之一,要求的是成段更新+懒惰标记。PS:原题的说明有问题,上面说的“C a b c”中的c的范围其实在int32之外,需要使用long long,否则定是WA,真心坑爹,连WA多次,还是在discuss中看到的原因。
     
    稍微讲解下代码中的一些细节: step<<1 与 step<<1|1,意思分别是step*2 和step*+1,具体为什么,可以回去复习一下位运算
     
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<map>
      9 
     10 #define N 100010
     11 #define M 15
     12 #define mod 1000000007
     13 #define mod2 100000000
     14 #define ll long long
     15 #define maxi(a,b) (a)>(b)? (a) : (b)
     16 #define mini(a,b) (a)<(b)? (a) : (b)
     17 
     18 using namespace std;
     19 
     20 int n,q;
     21 int x[N];
     22 char ch;
     23 int a,b,c;
     24 
     25 struct node
     26 {
     27     ll mark,sum;
     28 }tree[4*N];
     29 
     30 void update(int l,int r,int i)
     31 {
     32     if(!tree[i].mark) return;
     33     int mid=(l+r)/2;
     34     tree[2*i].sum+=tree[i].mark*(ll)(mid-l+1);
     35     tree[2*i+1].sum+=tree[i].mark*(ll)(r-mid);
     36     tree[2*i].mark+=tree[i].mark;
     37     tree[2*i+1].mark+=tree[i].mark;
     38     tree[i].mark=0;
     39 
     40 }
     41 
     42 ll query(int tl,int tr,int l,int r,int i)
     43 {
     44     if(tl>r || tr<l)
     45         return 0;
     46     if(tl<=l && r<=tr)
     47         return tree[i].sum;
     48     update(l,r,i);
     49     int mid=(l+r)/2;
     50 
     51     return query(tl,tr,l,mid,2*i)+query(tl,tr,mid+1,r,2*i+1);
     52 }
     53 
     54 void addd(int tl,int tr,int l,int r,int i,int val)
     55 {
     56     if(tl>r || tr<l)
     57         return;
     58     if(tl<=l && tr>=r){
     59         tree[i].sum+=val*(ll)(r-l+1);
     60         tree[i].mark+=val;
     61         return;
     62     }
     63     update(l,r,i);
     64     int mid=(l+r)/2;
     65     addd(tl,tr,l,mid,2*i,val);
     66     addd(tl,tr,mid+1,r,2*i+1,val);
     67     tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;
     68 }
     69 
     70 void build_tree(int l,int r,int i)
     71 {
     72     if(l==r){
     73         tree[i].sum=x[l];
     74         return;
     75     }
     76     int mid=(l+r)/2;
     77     build_tree(l,mid,2*i);
     78     build_tree(mid+1,r,2*i+1);
     79     tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;
     80 }
     81 
     82 int main()
     83 {
     84     int i;
     85    // freopen("data.in","r",stdin);
     86     //scanf("%d",&T);
     87     //for(int cnt=1;cnt<=T;cnt++)
     88     //while(T--)
     89     while(scanf("%d%d",&n,&q)!=EOF)
     90     {
     91        // printf(" %d %d 
    ",n,q);
     92        for(i=1;i<=n;i++) scanf("%d",&x[i]);
     93       // printf(" 1
    ");
     94        memset(tree,0,sizeof(tree));
     95        build_tree(1,n,1);
     96 
     97 
     98       //  printf(" 2
    ");
     99        getchar();
    100        while(q--){
    101           //  printf(" 3
    ");
    102             scanf("%c",&ch);
    103           //  printf(" %c
    ",ch);
    104             if(ch=='C'){
    105                 //printf(" 31
    ");
    106                 scanf("%d%d%d",&a,&b,&c);
    107                 getchar();
    108                 addd(a,b,1,n,1,c);
    109 
    110             }
    111             else{
    112                   //  printf(" 32
    ");
    113                 scanf("%d%d",&a,&b);
    114                 getchar();
    115                 ll ans=query(a,b,1,n,1);
    116                 printf("%I64d
    ",ans);
    117             }
    118        }
    119     }
    120 
    121     return 0;
    122 }
  • 相关阅读:
    面试题: !=!=未看12 略多 sql语句练习 非常 有用
    面试题--阿里
    LeetCode--Count Primes
    (转载)协方差的意义
    LeetCode--Isomorphic Strings
    LeetCode--Reverse Linked List(Java)
    JDBC连接数据库的过程
    (转载)Java中如何遍历Map对象的4种方法
    Ubuntu下Eclipse中运行Hadoop程序的参数问题
    Hadoop上配置Hbase数据库
  • 原文地址:https://www.cnblogs.com/njczy2010/p/3917501.html
Copyright © 2011-2022 走看看