zoukankan      html  css  js  c++  java
  • poj 3468 A Simple Problem with Integers 线段树

      这道题属于线段树的区间修改

    给出一个序列,对其进行Q次操作,

    "C c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q b" means querying the sum of AaAa+1, ... , Ab.

    注意,这道题我wa了4次,在那里查了3个小时,wa原因,一个应该是long long 型的被我写成了int  ,悲剧的开始。

        讲讲我对线段树区间修改的理解吧。

        需要有个操作,建树,更新,维护,查询。

      1.建树:首先就是把数据建起来嘛,是一个dfs的过程,对于一个节点,若该节点的区间只有一个,则为叶子节点,对该叶子进行赋值,否则建其左子树,和右子树,

    然后在递归结束前进行维护,更新该节点本身的信息。

      2.更新:更新的时候不断递归,直到递归边界 (L<=l&&R>=r),对于每一个递归,在递归结束之前需要重新计算本节点的附加信息。

      3.维护:维护就是维护一个节点的信息,2中说要在递归 结束之前重新计算本节点的附加信息,怎么计算,就是用到维护这个操作了。

      4查询:查询的时候是不断递归,直到递归边界(L<=l&&R>=r) 时,用边界区间的附加信息更新答案。

      sum[i] : 维护 i 对应区间的数据的和。

         addv[i] : 表示 i 对应区间的每一个数据都需要加 addv[i] ,所以每一个边界区间的结果不能直接使用,还要考虑祖先节点对她的影响。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define lson l,m,rt<<1
     4 #define rson m+1,r,rt<<1|1
     5 const int maxn=100000+10;
     6 long long  sum[maxn<<2];
     7 long long  addv[maxn<<2];
     8 void maintain(int l,int r,int rt)
     9 {
    10     sum[rt]=0;
    11     if(r>l)
    12         sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    13     sum[rt]+=addv[rt]*(r-l+1);
    14 }
    15 void build(int l,int r,int rt)
    16 {
    17     if(l==r){
    18         scanf("%I64d",&addv[rt]);
    19     }
    20     else{
    21         int m=(l+r)>>1;
    22         build(lson);
    23         build(rson);
    24     }
    25     maintain(l,r,rt);
    26 }
    27 void update(int L,int R,int  w,int l,int r,int rt)
    28 {
    29     if(L<=l&&R>=r){
    30         addv[rt]+=w;
    31     }
    32     else{
    33         int m=(l+r)>>1;
    34         if(L<=m)
    35             update(L,R,w,lson);
    36         if(R>m)
    37             update(L,R,w,rson);
    38     }
    39     maintain(l,r,rt);
    40 }
    41 long long  _sum;
    42 void query(int L,int R,int l,int r,int rt,long long  add)
    43 {
    44     if(L<=l&&R>=r)
    45         _sum+=sum[rt]+add*(r-l+1);
    46     else{
    47         int m=(l+r)>>1;
    48         if(L<=m)
    49             query(L,R,lson,add+addv[rt]);
    50         if(R>m)
    51             query(L,R,rson,add+addv[rt]);
    52     }
    53 }
    54 int main()
    55 {
    56     int n,q;
    57     while(scanf("%d%d",&n,&q)!=EOF)
    58     {
    59         memset(addv,0,sizeof(addv));
    60         build(1,n,1);
    61         char s[3];
    62         int u,v,w;
    63         for(int i=1;i<=q;i++){
    64             scanf("%s",&s);
    65             if(s[0]=='C'){
    66                 scanf("%d%d%d",&u,&v,&w);
    67                 update(u,v,w,1,n,1);
    68             }
    69             else{
    70                 scanf("%d%d",&u,&v);
    71                 _sum=0;
    72                 query(u,v,1,n,1,0);
    73                 printf("%I64d
    ",_sum);
    74             }
    75         }
    76     }
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    [十七]SpringBoot 之 使用自定义的properties
    【转】手摸手,带你用vue撸后台 系列三(实战篇)
    【转】手摸手,带你用vue撸后台 系列四(vueAdmin 一个极简的后台基础模板)
    【转】手摸手,带你用vue撸后台 系列二(登录权限篇)
    【转】手摸手,带你用vue撸后台 系列一
    【16】vuex2.0 之 getter
    【15】vuex2.0 之 modules
    【14】vuex2.0 之 mutation 和 action
    【13】vuex2.0 之 state
    【12】vue-router 之路由重定向
  • 原文地址:https://www.cnblogs.com/-maybe/p/4352214.html
Copyright © 2011-2022 走看看