为什么前面的人都跑得那么快啊?
QAQ
T1:区间方差
题目大意:询问区间方差,支持单点修改
首先把方差的式子展开,得到
$$d = \frac{a_1 + ... a_n}{n} - \frac{a_1^2 + .. + a_n^2 }{n^2}$$
那么,只需维护$\sum a_i$和$\sum a_i^2$即可
(没有区间加真是良心)
复杂度$O(n \log n)$
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> namespace remoon { #define ri register int #define tpr template <typename ra> #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++) #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --) #define gc getchar inline int read() { int p = 0, w = 1; char c = gc(); while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); } while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc(); return p * w; } } using namespace std; using namespace remoon; namespace mod_zone { const int mod = 1e9 + 7; inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; } inline void dec(int &a, int b) { a -= b; if(a < 0) a += mod; } inline int Inc(int a, int b) { return (a + b >= mod) ? a + b - mod : a + b; } inline int Dec(int a, int b) { return (a - b < 0) ? a - b + mod : a - b; } inline int mul(int a, int b) { return 1ll * a * b % mod; } inline int fp(int a, int k) { int ret = 1; for( ; k; k >>= 1, a = mul(a, a)) if(k & 1) ret = mul(ret, a); return ret; } } using namespace mod_zone; const int sid = 500050; int n, m; int w[sid], s[sid], s2[sid]; #define ls (o << 1) #define rs (o << 1 | 1) inline void upd(int o) { s[o] = Inc(s[ls], s[rs]); s2[o] = Inc(s2[ls], s2[rs]); } inline void build(int o, int l, int r) { if(l == r) { s[o] = w[l]; s2[o] = mul(w[l], w[l]); return; } int mid = (l+ r) >> 1; build(ls, l, mid); build(rs, mid + 1, r); upd(o); } inline void mdf(int o, int l, int r, int p, int v) { if(l == r) { s[o] = v; s2[o] = mul(v, v); return; } int mid = (l + r) >> 1; if(p <= mid) mdf(ls, l, mid, p, v); else mdf(rs, mid + 1, r, p, v); upd(o); } inline int qrys(int o, int l, int r, int ml, int mr) { if(ml > r || mr < l) return 0; if(ml <= l && mr >= r) return s[o]; int mid = (l + r) >> 1; return Inc(qrys(ls, l, mid, ml, mr), qrys(rs, mid + 1, r, ml, mr)); } inline int qryS(int o, int l, int r, int ml, int mr) { if(ml > r || mr < l) return 0; if(ml <= l && mr >= r) return s2[o]; int mid = (l + r) >> 1; return Inc(qryS(ls, l, mid, ml, mr), qryS(rs, mid + 1, r, ml, mr)); } int main() { n = read(); m = read(); rep(i, 1, n) w[i] = read(); build(1, 1, n); rep(i, 1, m) { int c = read(), a = read(), b = read(); if(c == 1) mdf(1, 1, n, a, b); else { int S = qrys(1, 1, n, a, b); int S2 = qryS(1, 1, n, a, b); int iv = fp(b - a + 1, mod - 2); int ans = Dec(mul(b - a + 1, S2), mul(S, S)); printf("%d\n", mul(ans, mul(iv, iv))); } } return 0; }