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 }
  • 相关阅读:
    单例模式
    说说抽象类接口
    闲说多态
    理解C#中的继承
    可变个数的形参的方法
    java 关键字
    数组的常见异常
    内存的基本结构 图片
    Java中的名称命名规范:
    死锁的例子 代码练习
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3237222.html
Copyright © 2011-2022 走看看