为什么前面的人都跑得那么快啊?

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;
}
1

相关文章: