• 线段树


    题目大意:一个线段树支持下面4中操作。

    1.对于一个区间[l,r]把区间中的每个元素加c;

    2.对于一个区间[l,r]把区间中的每个元素减c;

    3.对于一个区间[l,r]把区间中的每个元素置c;

    4.对于一个区间[l,r]求区间的和,并把这个和加到列表的每个元素上。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int imax_n = 10005;
      5 const long long PP = 1000000009;
      6 
      7 struct Node
      8 {
      9     int l, r;
     10     long long sum;
     11     long long val;
     12     long long c;
     13     long long s;
     14 }f[8 * imax_n];
     15 
     16 long long a[imax_n];
     17 int n, m;
     18 
     19 void build(int t, int l, int r, long long *a)
     20 {
     21     // printf("build %d %d %d
    ", t, l, r);
     22     f[t].l = l;
     23     f[t].r = r;
     24     f[t].val = 0LL;
     25     f[t].c = 0LL;
     26     f[t].s = 0LL;
     27     if (l == r)
     28     {
     29         // printf("add = %d
    ", a[l-1]);
     30         f[t].val = a[l-1];
     31         f[t].sum = a[l-1];
     32         // printf("%lld
    ", f[t].sum);
     33         return ;
     34     }
     35     int mid = (l + r) / 2;
     36     build(2*t, l , mid, a);
     37     build(2*t+1, mid+1, r, a);
     38     f[t].sum = (f[2*t].sum + f[2*t+1].sum) % PP;
     39 }
     40 
     41 void pushDown(int t)
     42 {
     43     if (f[t].s)
     44     {
     45         f[2*t].s = f[t].s;
     46         f[2*t+1].s = f[t].s;
     47         f[2*t].val = f[t].val;
     48         f[2*t].sum = f[t].val * (f[2*t].r - f[2*t].l + 1) % PP;
     49         f[2*t + 1].val = f[t].val;
     50         f[2*t + 1].sum = f[t].val * (f[2*t + 1].r - f[2*t+1].l + 1) % PP;
     51         f[t].s = 0LL;
     52         f[t].c = 0LL;
     53         f[t].val = 0LL;
     54     }
     55 
     56     if (f[t].c)
     57     {
     58         f[2*t].c = (f[2*t].c + f[t].c) % PP;
     59         f[2*t+1].c  = (f[2*t+1].c + f[t].c) %PP;
     60         f[2*t].sum = (f[2*t].sum + f[t].c * (f[2*t].r - f[2*t].l + 1)) % PP;
     61         f[2*t + 1].sum = (f[2*t+1].sum + f[t].c * (f[2*t+1].r - f[2*t+1].l + 1)) % PP;
     62         f[t].c = 0;
     63     }
     64 }
     65 
     66 void pushUp(int t)
     67 {
     68     f[t].sum = (f[2*t].sum + f[2*t+1].sum) % PP;
     69 }
     70 
     71 void modify(int t, int l, int r, int c)
     72 {
     73     if (f[t].l == l && f[t].r == r)
     74     {
     75         if (f[t].s)
     76             f[t].val = (f[t].val + c) % PP;
     77         else
     78             f[t].c = (f[t].c + c) % PP;
     79         f[t].sum = (f[t].sum + (long long )c * (f[t].r - f[t].l + 1)) % PP;
     80         return ;
     81     }
     82 
     83     pushDown(t);
     84     int mid = (f[t].l + f[t].r) / 2;
     85     if (r<=mid) modify(2*t, l, r, c);
     86     else if (l > mid) modify(2*t+1, l, r, c);
     87     else
     88     {
     89         modify(2*t, l, mid, c);
     90         modify(2*t+1, mid + 1, r, c);
     91     }
     92     pushUp(t);
     93 }
     94 
     95 void set_(int t, int l, int r, int val)
     96 {
     97     // printf("set_ %d %d %d
    ", t, l, r);
     98     if (f[t].l == l && f[t].r == r)
     99     {
    100         f[t].s = 1LL;
    101         f[t].val = (long long )val;
    102         f[t].sum = f[t].val* (f[t].r - f[t].l + 1) % PP;
    103         return;
    104     }
    105     pushDown(t);
    106     int mid = (f[t].l + f[t].r) / 2;
    107     if (r <= mid) set_(2*t, l, r, val);
    108     else if (l > mid) set_(2*t+1, l, r, val);
    109     else
    110     {
    111         set_(2*t, l, mid, val);
    112         set_(2*t+1, mid+1, r, val);
    113     }
    114     pushUp(t);
    115 }
    116 
    117 long long query(int t, int l, int r)
    118 {
    119     if (f[t].l == l && f[t].r == r)
    120     {
    121         return f[t].sum % PP;
    122     }
    123     pushDown(t);
    124     int mid = (f[t].l + f[t].r) / 2;
    125     if (r<=mid) return query(2*t, l, r);
    126     else if (l > mid) return query(2*t + 1, l, r);
    127     else
    128     {
    129         return (query(2*t, l, mid) + query(2*t+1, mid+1, r)) % PP;
    130     }
    131 }
    132 
    133 void print_tree(int t)
    134 {
    135     printf("node: %d l=%d r=%d s=%lld c=%lld sum=%lld
    ", t, f[t].l, f[t].r, f[t].s, f[t].c, f[t].sum);
    136     if (f[t].l == f[t].r)
    137     {
    138         return;
    139     }
    140     print_tree(2*t);
    141     print_tree(2*t+1);
    142 }
    143 
    144 void dfs(int t, vector<int> &ans)
    145 {
    146 
    147     if (f[t].l == f[t].r)
    148     {
    149         ans.push_back((int)(f[t].sum%PP));
    150         return ;
    151     }
    152     pushDown(t);
    153     dfs(2*t, ans);
    154     dfs(2*t+1, ans);
    155     pushUp(t);
    156 }
    157 
    158 int main()
    159 {
    160     scanf("%d%d", &n, &m);
    161     for (int i = 0; i < n; ++i)
    162     {
    163         scanf("%lld", &a[i]);
    164     }
    165     build(1, 1, n, a);
    166     // print_tree(1);
    167     long long op4 = 0LL;
    168     for (int i = 0; i < m; ++i)
    169     {
    170         int op, x, y, c;
    171         scanf("%d%d%d%d", &op, &x, &y, &c);
    172         if (op==1)
    173         {
    174             modify(1, x, y, c);
    175             // print_tree(1);
    176         }
    177         else if (op==2)
    178         {
    179             modify(1, x, y, -c);
    180             // print_tree(1);
    181         }
    182         else if (op==3)
    183         {
    184             set_(1, x, y, c);
    185             // print_tree(1);
    186         }
    187         else
    188         {
    189             op4 = query(1, x, y) % PP;
    190             // printf("qeury %d %d op4 = %lld
    ", x, y, op4);
    191             modify(1, 1, n, op4);
    192         }
    193     }
    194     vector<int> ans;
    195     dfs(1, ans);
    196     for (int i = 0; i < ans.size(); ++i)
    197     {
    198         printf("%d ", ans[i]);
    199     }
    200     printf("
    ");
    201     return 0;
    202 }
  • 相关阅读:
    Markdown学习笔记
    Go 学习笔记(一)
    case中定义变量
    <转>MySql 与Oracle区别
    Java 时间转换问题总结
    线程之间共享
    并发编程快速入门
    redis主从复制
    jedis操作redis
    redis持久化方案
  • 原文地址:https://www.cnblogs.com/djingjing/p/8710408.html
Copyright © 2020-2023  润新知