• #6029. 「雅礼集训 2017 Day1」市场 [线段树]


    考虑到每次除法,然后加法,差距会变小,于是维护加法lazytag即可

    #include <cstdio>
    #include <cmath>
    #define int long long
    int read() {
      int x = 0;
      bool f = 0;
      char c = getchar();
      while (c < 48) f ^= (c == '-'), c = getchar();
      while (c > 47) x = x * 10 + (c - 48), c = getchar();
      return f ? -x : x;
    }
    
    int n, m;
    const int maxn = 1e5 + 51;
    int a[maxn];
    int mn[maxn << 2], mx[maxn << 2];
    int del[maxn << 2], sum[maxn << 2];
    int min(int x, int y) { return x < y ? x : y; }
    int max(int x, int y) { return x > y ? x : y; }
    void pushup(int rt) {
      mn[rt] = min(mn[rt << 1], mn[rt << 1 | 1]);
      mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]);
      sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
    
    void build(int l, int r, int rt) {
      if (l == r) {
        sum[rt] = mn[rt] = mx[rt] = a[l];
        return;
      }
      int mid = l + r >> 1;
      build(l, mid, rt << 1);
      build(mid + 1, r, rt << 1 | 1);
      pushup(rt);
    }
    
    void pushtag(int l, int r, int rt, int x) {
      del[rt] += x, mn[rt] += x, mx[rt] += x;
      sum[rt] += x * (r - l + 1);
    }
    
    void pushd(int l, int r, int rt) {
      if (!del[rt]) return;
      int mid = l + r >> 1;
      pushtag(l, mid, rt << 1, del[rt]);
      pushtag(mid + 1, r, rt << 1 | 1, del[rt]);
      del[rt] = 0;
    }
    
    void modify(int a, int b, int l, int r, int rt, int v) {
      if (a <= l && r <= b) {
        pushtag(l, r, rt, v);
        return;
      }
      pushd(l, r, rt);
      int mid = l + r >> 1;
      if (a <= mid) modify(a, b, l, mid, rt << 1, v);
      if (b > mid) modify(a, b, mid + 1, r, rt << 1 | 1, v);
      pushup(rt);
    }
    
    void div(int a, int b, int l, int r, int rt, int v) {
      if (a <= l && r <= b) {
        int tx = floor((double)mx[rt] / v);
        int ty = floor((double)mn[rt] / v);
        if (tx - mx[rt] == ty - mn[rt]) {
          pushtag(l, r, rt, tx - mx[rt]);
          return;
        }
        pushd(l, r, rt);
        int mid = l + r >> 1;
        div(a, b, l, mid, rt << 1, v), div(a, b, mid + 1, r, rt << 1 | 1, v);
        pushup(rt);
        return;
      }
      pushd(l, r, rt);
      int mid = l + r >> 1;
      if (a <= mid) div(a, b, l, mid, rt << 1, v);
      if (b > mid) div(a, b, mid + 1, r, rt << 1 | 1, v);
      pushup(rt);
    }
    
    int qry(int a, int b, int l, int r, int rt) {
      if (a <= l && r <= b) return sum[rt];
      pushd(l, r, rt);
      int mid = l + r >> 1;
      int ans = 0;
      if (a <= mid) ans = qry(a, b, l, mid, rt << 1);
      if (b > mid) ans += qry(a, b, mid + 1, r, rt << 1 | 1);
      return ans;
    }
    
    int qrymin(int a, int b, int l, int r, int rt) {
      if (a <= l && r <= b) return mn[rt];
      pushd(l, r, rt);
      int mid = l + r >> 1;
      int ans = 1e18;
      if (a <= mid) ans = min(ans, qrymin(a, b, l, mid, rt << 1));
      if (b > mid) ans = min(ans, qrymin(a, b, mid + 1, r, rt << 1 | 1));
      return ans;
    }
    
    signed main() {
      n = read(), m = read();
      for (int i = 1; i <= n; i++) a[i] = read();
      build(1, n, 1);
      while (m--) {
        int op;
        op = read();
        if (op == 1) {
          int l, r, x;
          l = read(), r = read(), x = read();
          ++l, ++r;
          modify(l, r, 1, n, 1, x);
        }
        if (op == 2) {
          int l, r, x;
          l = read(), r = read(), x = read();
          ++l, ++r;
          div(l, r, 1, n, 1, x);
        }
        if (op == 3) {
          int l, r;
          l = read(), r = read();
          ++l, ++r;
          printf("%lld
    ", qrymin(l, r, 1, n, 1));
        }
        if (op == 4) {
          int l, r;
          l = read(), r = read();
          ++l, ++r;
          printf("%lld
    ", qry(l, r, 1, n, 1));
        }
      }
      return 0;
    }
    
  • 相关阅读:
    Codeforces Round #620 (Div. 2)
    Codeforces Round #575 (Div. 3)
    Codeforces Round #619 (Div. 2)
    2014 Nordic Collegiate Programming Contest
    Educational Codeforces Round 82 (Rated for Div. 2)
    模板
    2015-2016 ACM-ICPC Southwestern Europe Regional Contest (SWERC 15)
    模板
    Codeforces Round #618 (Div. 2)
    Codeforces Round #343 (Div. 2)
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12356655.html
Copyright © 2020-2023  润新知