蒟蒻,线段树10pts求调
查看原帖
蒟蒻,线段树10pts求调
480778
Charles_Fan楼主2023/11/9 15:38
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int N = 1e5, mod = 1e9 + 7;
int n, q;

inline int qpow(int a, int n) {
  int ret = 1;
  while (n) {
    if (n & 1) ret = (ret * a) % mod;
    n >>= 1;
    a = (a * a) % mod;
  }
  return ret;
}
int inv(int x) { return qpow(x, mod - 2); }

class SegmentTree {
#define lc(x) ((x) << 1)
#define rc(x) (((x) << 1) | 1)
 private:
  int n, sum[N << 2], sq[N << 2];
  void pushup(int cur) {
    sum[cur] = (sum[lc(cur)] + sum[rc(cur)]) % mod;
    sq[cur] = (sq[lc(cur)] + sq[rc(cur)]) % mod;
  }
  void build(int cur, int l, int r) {
    if (l == r) {
      scanf("%lld", &sum[l]);
      sum[l] %= mod;
      sq[l] = (sum[l] * sum[l]) % mod;
      return;
    }
    int mid = (l + r) >> 1;
    build(lc(cur), l, mid);
    build(rc(cur), mid + 1, r);
    pushup(cur);
  }
  void modify(int cur, int l, int r, int x, int val) {
    if (l == r) {
      sum[cur] = val;
      sq[cur] = (val * val) % mod;
      return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid)
      modify(lc(cur), l, mid, x, val);
    else
      modify(rc(cur), mid + 1, r, x, val);
    pushup(cur);
  }
  int query_sum(int cur, int l, int r, int x, int y) {
    if (x <= l && r <= y) return sum[cur];
    int mid = (l + r) >> 1;
    int ret = 0;
    if (x <= mid) ret = (ret + query_sum(lc(cur), l, mid, x, y)) % mod;
    if (y >= mid + 1) ret = (ret + query_sum(rc(cur), mid + 1, r, x, y)) % mod;
    return ret % mod;
  }
  int query_sq(int cur, int l, int r, int x, int y) {
    if (x <= l && r <= y) return sq[cur];
    int mid = (l + r) >> 1;
    int ret = 0;
    if (x <= mid) ret = (ret + query_sq(lc(cur), l, mid, x, y)) % mod;
    if (y >= mid + 1) ret = (ret + query_sq(rc(cur), mid + 1, r, x, y)) % mod;
    return ret % mod;
  }

 public:
  void build(int _n) {
    n = _n;
    build(1, 1, n);
  }
  void modify(int x, int val) { modify(1, 1, n, x, val); }
  int query_sum(int l, int r) { return query_sum(1, 1, n, l, r); }
  int query_sq(int l, int r) { return query_sq(1, 1, n, l, r); }
  int query_variance(int l, int r) {
    int avg = (query_sum(l, r) * inv(r - l + 1)) % mod;
    return (((query_sq(l, r) * inv(r - l + 1)) % mod - (avg * avg) % mod) %
                mod +
            mod) %
           mod;
  }
} st;

signed main() {
#ifdef LOCAL
  freopen("input.in", "r", stdin);
#endif
  scanf("%lld%lld", &n, &q);
  st.build(n);
  while (q--) {
    int op, l, r;
    scanf("%lld%lld%lld", &op, &l, &r);
    if (op == 1)
      st.modify(l, r);
    else {
      // printf("%lld %lld:\nsum=%lld\nsq=%lld\n", l, r, st.query_sum(l, r),
      //        st.query_sq(l, r));
      printf("%lld\n", st.query_variance(l, r));
    }
  }
  return 0;
}
2023/11/9 15:38
加载中...