zoukankan      html  css  js  c++  java
  • 线段树专辑—— pku 3468 A Simple Problem with Integers

    http://poj.org/problem?id=3468

    典型的一道基于lazy传递的线段树题目,这题和一般题目不同的地方在于,它的每次操作不是简单的覆盖线段,而是累加。记得第一次写的时候纠结了好久。

    好的,既然是累加,那么如何传递lazy呢?答案是传递累加值!

    为线段树加一个add域,表示该线段需要加几。如果某区间的add不为0,那么就将该区间的add传递给其子区间,并且跟新子区间的sum_val值。

    解这题最关键的就是要能够分清楚啥东西要传递,传递下去将有什么影响,其他的都好说!整体来说还是蛮轻松的

    View Code
      1 #include<iostream>
    2 #include<string>
    3 #include<algorithm>
    4 using namespace std;
    5
    6 struct node
    7 {
    8 int l;
    9 int r;
    10 __int64 add;
    11 __int64 sum_val;
    12 };
    13
    14 node tree[500000];
    15 int n,m;
    16 __int64 num[100001];
    17
    18 void build(int i,int l,int r)
    19 {
    20 tree[i].l=l;
    21 tree[i].r=r;
    22 tree[i].add=0;
    23 if(l==r)
    24 {
    25 tree[i].sum_val=num[l];
    26 return;
    27 }
    28 int mid=(l+r)/2;
    29 build(2*i,l,mid);
    30 build(2*i+1,mid+1,r);
    31 tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val;
    32 }
    33
    34 void updata(int i,int l,int r,__int64 w)
    35 {
    36 if(tree[i].l>r || tree[i].r<l)
    37 return;
    38 if(tree[i].l>=l && tree[i].r<=r)
    39 {
    40 tree[i].add+=w; //注意是+=,因为这不是简单的覆盖
    41 tree[i].sum_val+=(tree[i].r-tree[i].l+1)*w; //由于区间所有的值都需要加上w,那么自然整段区间就是加上(w*区间大小)了
    42 return;
    43 }
    44 if(tree[i].add!=0)
    45 {
    46 tree[2*i].add+=tree[i].add; //同上,注意是+=
    47 tree[2*i+1].add+=tree[i].add;
    48 tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add;
    49 tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add;
    50 tree[i].add=0;
    51 }
    52 updata(2*i,l,r,w);
    53 updata(2*i+1,l,r,w);
    54 tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val; //回溯跟新
    55 }
    56
    57 __int64 ans;
    58 void find(int i,int l,int r)
    59 {
    60 if(tree[i].l>r || tree[i].r<l)
    61 return;
    62 if(tree[i].l>=l && tree[i].r<=r)
    63 {
    64 ans+=tree[i].sum_val;
    65 return;
    66 }
    67 if(tree[i].add!=0)
    68 {
    69 tree[2*i].add+=tree[i].add;
    70 tree[2*i+1].add+=tree[i].add;
    71 tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add;
    72 tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add;
    73 tree[i].add=0;
    74 }
    75 find(2*i,l,r);
    76 find(2*i+1,l,r);
    77 }
    78
    79 int main()
    80 {
    81 int i,a,b;
    82 __int64 w;
    83 char c;
    84 freopen("in.txt","r",stdin);
    85 while(scanf("%d%d",&n,&m)==2)
    86 {
    87 for(i=1;i<=n;i++)
    88 {
    89 scanf("%I64d",&num[i]);
    90 }
    91 build(1,1,n);
    92 for(i=0;i<m;i++)
    93 {
    94 getchar();
    95 scanf("%c",&c);
    96 if(c=='Q')
    97 {
    98 scanf("%d%d",&a,&b);
    99 ans=0;
    100 find(1,a,b);
    101 printf("%I64d\n",ans);
    102 }
    103 else
    104 {
    105 scanf("%d%d%I64d",&a,&b,&w);
    106 updata(1,a,b,w);
    107 }
    108 }
    109 }
    110 return 0;
    111 }
  • 相关阅读:
    波松分酒问题 C++求最优解. Anthony
    Effective STL 条款7 Anthony
    Effective STL 条款16 Anthony
    数据库设计经验之谈[转载]
    C#递归在dropdownlist显示树状
    多域名同主机js转向
    ASP.NET中常用的26个优化性能方法
    域名解析、子域名、cname别名指向、MX记录、泛域名与泛解析、域名绑定、域名转向
    C#数据库递归构造treeview树形结构
    ASP.NET多种方式生成高质量缩略图
  • 原文地址:https://www.cnblogs.com/ka200812/p/2243657.html
Copyright © 2011-2022 走看看