• 4821: [Sdoi2017]相关分析


    4821: [Sdoi2017]相关分析

    链接

    分析:

      大力拆式子,化简,然后线段树。注意精度问题与爆longlong问题。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    #define Root 1, n, 1
    #define lc rt << 1
    #define rc rt << 1 | 1
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    using namespace std;
    typedef double DB;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 100005;
    DB sx[N << 2], sy[N << 2], s[N << 2], s2[N << 2], tag[N << 2], taga[N << 2], tagb[N << 2], X[N], Y[N];
    DB sum[N], sum2[N];
    DB Sx, Sy, S, S2;
    int n;
    
    inline void pushup(int rt) {
        sx[rt] = sx[lc] + sx[rc];
        sy[rt] = sy[lc] + sy[rc];
        s2[rt] = s2[lc] + s2[rc];
        s[rt] = s[lc] + s[rc];
    }
    inline void col(int rt,int l,int r) {
        sy[rt] = sx[rt] = sum[r] - sum[l - 1];
        s2[rt] = s[rt] = sum2[r] - sum2[l - 1];
        tag[rt] = 1; taga[rt] = tagb[rt] = 0;
    }
    inline void add(int rt,DB len,DB a,DB b) {
        s[rt] += sx[rt] * b + sy[rt] * a + a * b * len;
        s2[rt] += a * a * len + 2 * a * sx[rt];
        sx[rt] += a * len;
        sy[rt] += b * len;
        taga[rt] += a, tagb[rt] += b;
    }
    inline void pushdown(int rt,int l,int r) {
        int mid = (l + r) >> 1;
        if (tag[rt]) {
            col(lc, l, mid); col(rc, mid + 1, r);
            tag[rt] = 0; 
        }
        if (taga[rt] || tagb[rt]) { // !!!
            add(lc, mid - l + 1, taga[rt], tagb[rt]);
            add(rc, r - mid, taga[rt], tagb[rt]);
            taga[rt] = tagb[rt] = 0;
        }
    }
    void build(int l,int r,int rt) {
        if (l == r) {
            sx[rt] = X[l], sy[rt] = Y[l], s[rt] = X[l] * Y[l], s2[rt] = X[l] * X[l]; return ;
        }
        int mid = (l + r) >> 1;
        build(lson), build(rson);
        pushup(rt);
    }
    void update(int l,int r,int rt,int L,int R,DB a,DB b) {
        if (L <= l && r <= R) {
            add(rt, r - l + 1, a, b); return ;
        }
        int mid = (l + r) >> 1;
        pushdown(rt, l, r);
        if (L <= mid) update(lson, L, R, a, b);
        if (R > mid) update(rson, L, R, a, b);
        pushup(rt);
    }
    void Change(int l,int r,int rt,int L,int R) {
        if (L <= l && r <= R) {
            col(rt, l, r); return ;
        }
        int mid = (l + r) >> 1;
        pushdown(rt, l, r);
        if (L <= mid) Change(lson, L, R);
        if (R > mid) Change(rson, L, R);
        pushup(rt);
    }
    void query(int l,int r,int rt,int L,int R) {
        if (L <= l && r <= R) {
            Sx += sx[rt], Sy += sy[rt], S += s[rt], S2 += s2[rt]; return ;
        }
        int mid = (l + r) >> 1;
        pushdown(rt, l, r);
        if (L <= mid) query(lson, L, R);
        if (R > mid) query(rson, L, R);
    }
    void Ask() {
        int l = read(), r = read();
        Sx = Sy = S = S2 = 0;  
        query(Root, l, r); 
        double x = 1.0 * Sx / (r - l + 1), y = 1.0 * Sy / (r - l + 1);
    //    double u = S - Sy * x - Sx * y + x * y * (r - l + 1);
    //    double d = S2 + x * x * (r - l + 1) - 2 * Sx * x;
        double u = S - y * Sx, d = S2 - x * Sx;
        printf("%.10lf
    ", (double)(u / d));
    }
    void work1() {
        int l = read(), r = read();
        DB a = (DB)read(), b = (DB)read();
        update(Root, l, r, a, b);
    }
    void work2() {
        int l = read(), r = read();
        DB a = (DB)read(), b = (DB)read();
        Change(Root, l, r);
        update(Root, l, r, a, b);
    }
    int main() {
        n = read();int m = read();
        for (int i = 1; i <= n; ++i) {
            sum[i] = sum[i - 1] + 1.0 * i; 
            sum2[i] = sum2[i - 1] + 1.0 * i * i; // 此处报int !!! 
        }
        for (int i = 1; i <= n; ++i) X[i] = (DB)read();
        for (int i = 1; i <= n; ++i) Y[i] = (DB)read();
        build(Root);
        while (m --) {
            int opt = read();
            if (opt == 1) Ask();
            else if (opt == 2) work1();
            else work2();
        }
        return 0;
    }
  • 相关阅读:
    CSS之APP开发比较实用的CSS属性
    关于 js 中的 call 和 apply使用理解
    灵感一:搜索型APP,帮助读书爱好者,搜索某本书的关键字
    常用排序算法:基数排序
    常用排序算法:桶排序
    常用排序算法:计数排序
    常用排序算法:希尔排序
    常用排序算法:归并排序
    常用排序算法:堆排序
    常用排序算法:快速排序
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10385779.html
Copyright © 2020-2023  润新知