zoukankan      html  css  js  c++  java
  • poj 3468 线段树区间更新/查询

    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.
     
    题意:裸线段树 区间更新/查询 
     
    题解:线段树每次写都有不同程度的错误.too vegatable
    1.延迟标记的add 都要初始化为0 
    2.延迟的传递是累加而不是赋值
    具体看代码。
     
      1 /******************************
      2 code by drizzle
      3 blog: www.cnblogs.com/hsd-/
      4 ^ ^    ^ ^
      5  O      O
      6 ******************************/
      7 //#include<bits/stdc++.h>
      8 #include<iostream>
      9 #include<cstring>
     10 #include<cstdio>
     11 #include<map>
     12 #include<algorithm>
     13 #include<cmath>
     14 #define ll long long
     15 #define PI acos(-1.0)
     16 #define mod 1000000007
     17 using namespace std;
     18 struct node
     19 {
     20     ll l,r;
     21     ll add;
     22     ll sum;
     23 } tree[600005];
     24 void  buildtree(ll root,ll left,ll right)
     25 {
     26     tree[root].l=left;
     27     tree[root].r=right;
     28     tree[root].add=0;//wa点 所有的延迟标记都要初始化 
     29     if(left==right)//不能放到下面的if中
     30     {
     31 
     32         ll exm;
     33         scanf("%lld",&exm);
     34         tree[root].sum=exm;
     35         return ;
     36     }
     37     ll mid=(left+right)>>1;
     38     buildtree(root<<1,left,mid);
     39     buildtree(root<<1|1,mid+1,right);
     40     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
     41 }
     42 void pushdown(ll root)
     43 {
     44     if(tree[root].add==0) return ;
     45     tree[root<<1].add+=tree[root].add;//wa点 这里是增加而不是赋值
     46     tree[root<<1|1].add+=tree[root].add;
     47     tree[root<<1].sum+=(tree[root<<1].r-tree[root<<1].l+1)*tree[root].add;
     48     tree[root<<1|1].sum+=(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].add;
     49     tree[root].add=0;
     50 }
     51 void updata(ll root,ll left,ll right,ll c)
     52 {
     53     if(tree[root].l==left&&tree[root].r==right)
     54     {
     55         tree[root].add+=c;//wa点 这里是增加而不是赋值
     56         tree[root].sum+=(right-left+1)*c;
     57         return ;
     58     }
     59      pushdown(root);
     60     ll mid=(tree[root].l+tree[root].r)>>1;
     61     if(right<=mid)
     62         updata(root<<1,left,right,c);
     63     else
     64     {
     65         if(left>mid)
     66             updata(root<<1|1,left,right,c);
     67         else
     68         {
     69             updata(root<<1,left,mid,c);
     70             updata(root<<1|1,mid+1,right,c);
     71         }
     72     }
     73     tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
     74 }
     75 ll query(ll root,ll left,ll right)
     76 {
     77     if(tree[root].l==left&&tree[root].r==right)
     78     {
     79         return tree[root].sum;
     80     }
     81     pushdown(root);
     82     ll mid=(tree[root].l+tree[root].r)>>1;
     83     if(right<=mid)
     84         return query(root<<1,left,right);
     85     else
     86     {
     87         if(left>mid)
     88             return query(root<<1|1,left,right);
     89         else
     90             return query(root<<1,left,mid)+query(root<<1|1,mid+1,right);
     91     }
     92 }
     93 ll n,q;
     94 char what;
     95 ll l1,r1,ad;
     96 int main()
     97 {
     98     while(~scanf("%lld %lld",&n,&q))
     99     {
    100         buildtree(1,1,n);
    101         getchar();
    102         for(ll i=1; i<=q; i++)
    103         {
    104             scanf("%c %lld %lld",&what,&l1,&r1);
    105             if(what=='Q')
    106                 printf("%lld
    ",query(1,l1,r1));
    107             else
    108             {
    109                 scanf("%lld",&ad);
    110                 updata(1,l1,r1,ad);
    111             }
    112             getchar();
    113         }
    114     }
    115     return 0;
    116 }
    117 /*
    118 10 10
    119 1 2 3 4 5 6 7 8 9 10
    120 C 1 10 1
    121 Q 2 3
    122 
    123 10 10
    124 1 2 3 4 5 6 7 8 9 10
    125 C 1 5 1
    126 Q 4 6
    127 */
  • 相关阅读:
    python-学习 补充模块;面向对象程序设计
    python学习- 常用模块与re正则
    python-学习 协程函数 模块与包
    python-学习 初级atm小脚本、函数嵌套、装饰器、生成器、迭代器、三元表达式
    模拟登陆古诗文网
    正则表达式(括号)、[中括号]、{大括号}的区别
    MongoDB的基本操作
    语音合成以及语音识别
    flask中的CBV,flash,Flask-Session,WTForms
    Flask基础2 蓝图,实例化配置,app对象配置,特殊装饰器
  • 原文地址:https://www.cnblogs.com/hsd-/p/5718676.html
Copyright © 2011-2022 走看看