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

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

    A Simple Problem with Integers
    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 46488   Accepted: 13633
    Case Time Limit: 2000MS

    Description

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

    【题解】:
      本来以为简单的线段树,做了好久没做出来,思维还是不够清晰,然后重新理了一下思路,终于大彻大悟,嘿嘿!!!
      主要是对结尾区间的传递,以及线段区间的标记,想好这两部分就不难了。。。
    【code】:
      1 /**
      2 result:Accepted        memory:8368K
      3 time:1750MS       language:C++
      4 code lenght: 2655B   Acmer:cj
      5 
      6 */
      7 
      8 #include<iostream>
      9 #include<stdio.h>
     10 #include<string.h>
     11 #include<algorithm>
     12 
     13 #define N 100010
     14 #define lson p<<1
     15 #define rson p<<1|1
     16 using namespace std;
     17 
     18 struct Nod
     19 {
     20     int l,r;
     21     __int64 sum,val;  //区间和 以及 val记录 flag为1 时 val才有值,向下更新时用
     22     int flag; //标记是否为结尾区间
     23 }node[N<<2];
     24 
     25 void building(int l,int r,int p)
     26 {
     27     node[p].l = l;
     28     node[p].r = r;
     29     node[p].flag = 0;
     30     node[p].val = 0;
     31     if(l==r)
     32     {
     33         scanf("%I64d",&node[p].sum);
     34         return;
     35     }
     36     int mid = (l+r)>>1;
     37     building(l,mid,lson);
     38     building(mid+1,r,rson);
     39     node[p].sum = node[lson].sum + node[rson].sum;
     40 }
     41 
     42 void update(int l,int r,int p,__int64 c)
     43 {
     44     node[p].sum+=(r-l+1)*c;  //从上往下计算sum
     45     if(node[p].l==l&&r==node[p].r)
     46     {
     47         if(node[p].flag)    node[p].val+=c;  //如果已经被标记结尾区间 val+=c 尾部区间val再增加C
     48         else
     49         {
     50             node[p].flag = 1;  //如果是新增加的结尾区间
     51             node[p].val = c;  //赋值区间的val
     52         }
     53         return;
     54     }
     55     if(node[p].flag)  //如果遇到结尾区间,将结尾区间往下传递
     56     {
     57         node[p].flag = 0;
     58         node[lson].val+=node[p].val;
     59         node[rson].val+=node[p].val;
     60         node[lson].flag = node[rson].flag = 1;  //向下传递结尾区间标记
     61         node[lson].sum += node[p].val*(node[lson].r-node[lson].l+1);  //向下传递结尾区间sum值
     62         node[rson].sum += node[p].val*(node[rson].r-node[rson].l+1);  //同上
     63         node[p].val = 0;
     64     }
     65     int mid = (node[p].l+node[p].r)>>1;
     66     if(r<=mid)  update(l,r,lson,c);
     67     else if(l>mid)  update(l,r,rson,c);
     68     else
     69     {
     70         update(l,mid,lson,c);
     71         update(mid+1,r,rson,c);
     72     }
     73 }
     74 
     75 __int64 query(int l,int r,int p)
     76 {
     77     if(node[p].l==l&&node[p].r==r)  //找到区间返回sum值
     78     {
     79         return  node[p].sum;
     80     }
     81     if(node[p].flag)  //如果遇到结尾区间,将结尾区间往下传递
     82     {
     83         node[p].flag = 0;
     84         node[lson].val+=node[p].val;
     85         node[rson].val+=node[p].val;
     86         node[lson].flag = node[rson].flag = 1;  //向下传递结尾区间标记
     87         node[lson].sum += node[p].val*(node[lson].r-node[lson].l+1);  //向下传递结尾区间sum值
     88         node[rson].sum += node[p].val*(node[rson].r-node[rson].l+1);  //同上
     89         node[p].val = 0;
     90     }
     91     int mid = (node[p].l+node[p].r)>>1;
     92     if(r<=mid)  return query(l,r,lson);
     93     else if(l>mid)  return query(l,r,rson);
     94     else    return query(l,mid,lson)+query(mid+1,r,rson);
     95 }
     96 
     97 int main()
     98 {
     99     int n,q;
    100     scanf("%d%d",&n,&q);
    101     building(1,n,1);
    102     char op[5];
    103     while(q--)
    104     {
    105         scanf("%s",op);
    106         int a,b;
    107         __int64 c;
    108         if(op[0]=='Q')
    109         {
    110             scanf("%d%d",&a,&b);
    111             printf("%I64d
    ",query(a,b,1));
    112         }
    113         else if(op[0]=='C')
    114         {
    115             scanf("%d%d%I64d",&a,&b,&c);
    116             update(a,b,1,c);
    117         }
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    《ASP.NET Core跨平台开发从入门到实战》Web API自定义格式化protobuf
    .NET Core中文分词组件jieba.NET Core
    .NET Core 2.0及.NET Standard 2.0
    Visual Studio 2017 通过SSH 调试Linux 上.NET Core
    Visual Studio 2017 ASP.NET Core开发
    Visual Studio 2017正式版离线安装及介绍
    在.NET Core 上运行的 WordPress
    IT人员如何开好站立会议
    puppeteer(二)操作实例——新Web自动化工具更轻巧更简单
    puppeteer(一)环境搭建——新Web自动化工具(同selenium)
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3237222.html
Copyright © 2011-2022 走看看