zoukankan      html  css  js  c++  java
  • 18.10.16 luoguP3372 线段树模板-区间更新值&求和(POJ3468 A Simple Problem with Integers)

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数加上x

    2.求出某区间每一个数的和

    输入输出格式

    输入格式:

     

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含3或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x y 含义:输出区间[x,y]内每个数的和

     

    输出格式:

     

    输出包含若干行整数,即为所有操作2的结果。

     

    输入输出样例

    输入样例#1: 
    5 5
    1 5 4 2 3
    2 2 4
    1 2 3 2
    2 3 4
    1 1 5 1
    2 1 4
    输出样例#1: 
    11
    8
    20

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=1000,M<=10000

    对于100%的数据:N<=100000,M<=100000

    (数据已经过加强^_^,保证在int64/long long数据范围内)

    样例说明:

      1 #include <iostream>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <stack>
      5 #include <string>
      6 #include <math.h>
      7 #include <queue>
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <vector>
     11 #include <fstream>
     12 #include <set>
     13 #define l(rt) rt<<1
     14 #define r(rt) (rt<<1)+1
     15 
     16 using namespace std;
     17 const int maxn = 100005;
     18 int n, m;
     19 struct node {
     20     int l, r;
     21     long long sum,inc;
     22 }tree[maxn<<3];
     23 
     24 void build(int rt,int l,int r) {
     25     tree[rt].l = l, tree[rt].r = r;
     26     tree[rt].sum = tree[rt].inc = 0;
     27     if (l == r)return;
     28     int mid = (l + r) / 2;
     29     build(l(rt), l, mid);
     30     build(r(rt), mid + 1, r);
     31 }
     32 
     33 void change(int rt,int l,int r,long inc) {
     34     if (tree[rt].l == l && tree[rt].r == r) {
     35         tree[rt].inc += inc;
     36         return;
     37     }
     38     tree[rt].sum += inc * (r - l + 1);
     39     int mid = (tree[rt].l + tree[rt].r) / 2;
     40     if (l >= mid + 1)
     41         change(r(rt), l, r,inc);
     42     else if (r <= mid)
     43         change(l(rt), l, r,inc);
     44     else {
     45         change(l(rt), l, mid,inc);
     46         change(r(rt), mid+1, r,inc);
     47     }
     48 }
     49 
     50 long long query(int rt,int l, int r) {
     51     if (tree[rt].l == l && tree[rt].r == r) {
     52         tree[rt].sum += tree[rt].inc * (tree[rt].r - tree[rt].l + 1);
     53         tree[r(rt)].inc += tree[rt].inc;
     54         tree[l(rt)].inc += tree[rt].inc;
     55         tree[rt].inc = 0;
     56         return tree[rt].sum;
     57     }
     58     tree[rt].sum += tree[rt].inc * (tree[rt].r-tree[rt].l+1);
     59     tree[r(rt)].inc += tree[rt].inc;
     60     tree[l(rt)].inc += tree[rt].inc;
     61     tree[rt].inc = 0;
     62     int mid = (tree[rt].l + tree[rt].r) / 2;
     63     if (l > mid)
     64         return query(r(rt), l, r);
     65     else if (r <= mid)
     66         return query(l(rt), l, r);
     67     else
     68         return query(l(rt), l, mid) + query(r(rt), mid + 1, r);
     69 }
     70 
     71 void init() {
     72     scanf("%d%d", &n, &m);
     73     build(1, 1, n);
     74     for (int i = 1; i <= n; i++) {
     75         int x;
     76         scanf("%d", &x);
     77         change(1, i, i, x);
     78     }
     79     while (m--) {
     80         int oper;
     81         scanf("%d", &oper);
     82         if (oper == 1) {
     83             int x, y, k;
     84             scanf("%d%d%d", &x, &y, &k);
     85             change(1, x, y, k);
     86         }
     87         else if (oper == 2) {
     88             int x, y;
     89             scanf("%d%d", &x, &y);
     90             long long ans = query(1,x, y);
     91             printf("%lld
    ", ans);
     92         }
     93     }
     94 }
     95 
     96 int main()
     97 {
     98     init();
     99     return 0;
    100 }
    View Code

    是上课时的例题

    因为睡着了所以做一遍

    WA点:

    一开始把 query() 函数中更新 tree[rt].sum 的值时 tree[rt].inc 乘上的值写成了 r-l+1 ,显然是错误的……手误

    貌似 r(rt) 的表达式中必须加括号

    大致思路:延迟更新,避免TLE

    注定失败的战争,也要拼尽全力去打赢它; 就算输,也要输得足够漂亮。
  • 相关阅读:
    Count and Say leetcode
    Find Minimum in Rotated Sorted Array II leetcode
    Find Minimum in Rotated Sorted Array leetcode
    Search in Rotated Sorted Array II leetcode
    search in rotated sorted array leetcode
    Substring with Concatenation of All Words
    Subsets 子集系列问题 leetcode
    Sudoku Solver Backtracking
    Valid Sudoku leetcode
    《如何求解问题》-现代启发式方法
  • 原文地址:https://www.cnblogs.com/yalphait/p/9799119.html
Copyright © 2011-2022 走看看