zoukankan      html  css  js  c++  java
  • Codeforces #448 Div2 E

    #448 Div2 E

    题意

    给出一个数组,有两种类型操作:

    1. 选定不相交的两个区间,分别随机挑选一个数,交换位置。
    2. 查询区间和的期望。

    分析

    线段树区间更新区间求和。
    既然是涉及到两个区间,那么对于第一个区间而言,它的和的期望由两部分组成:它剩下的数的和的期望,从第二个区间换过来的数的和的期望。第二个区间同理。
    可以用两个数组分别(间接)维护这两部分的值(类似于线段树中常见的 lazy 数组)。

    code

    #include<bits/stdc++.h>
    using namespace std;
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    const int N = 4e5 + 10;
    double a[N], b[N], c[N];
    void pushDown(int l, int r, int rt) {
        int m = l + r >> 1;
        b[rt << 1] *= b[rt];
        c[rt << 1] = c[rt << 1] * b[rt] + c[rt];
        a[rt << 1] = c[rt] * (m - l + 1) + a[rt << 1] * b[rt];
        b[rt << 1 | 1] *= b[rt];
        c[rt << 1 | 1] = c[rt << 1 | 1] * b[rt] + c[rt];
        a[rt << 1 | 1] = c[rt] * (r - m) + a[rt << 1 | 1] * b[rt];
        b[rt] = 1;
        c[rt] = 0;
    }
    void build(int l, int r, int rt) {
        b[rt] = 1;
        if(l == r) scanf("%lf", &a[rt]);
        else {
            int m = l + r >> 1;
            build(lson);
            build(rson);
            a[rt] = a[rt << 1] + a[rt << 1 | 1];
        }
    }
    void update(double bb, double cc, int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) {
            b[rt] *= bb;
            c[rt] = c[rt] * bb + cc;
            a[rt] = cc * (r - l + 1) + a[rt] * bb;
        } else {
            pushDown(l, r, rt);
            int m = l + r >> 1;
            if(L <= m) update(bb, cc, L, R, lson);
            if(R > m) update(bb, cc, L, R, rson);
            a[rt] = a[rt << 1] + a[rt << 1 | 1];
        }
    }
    double query(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return a[rt];
        else {
            pushDown(l, r, rt);
            int m = l + r >> 1;
            double res = 0;
            if(L <= m) res += query(L, R, lson);
            if(R > m) res += query(L, R, rson);
            return res;
        }
    }
    int main() {
        int n, q;
        cin >> n >> q;
        build(1, n, 1);
        while(q--) {
            int idx, w[4];
            cin >> idx;
            for(int i = 0; i < 6 - 2 * idx; i++) scanf("%d", &w[i]);
            if(idx == 1) {
                double c1 = query(w[2], w[3], 1, n, 1) / ((double)w[1] - w[0] + 1), c2 = query(w[0], w[1], 1, n, 1) / ((double)w[3] - w[2] + 1);
                update(((double)w[1] - w[0]) / ((double)w[1] - w[0] + 1), c1 / ((double)w[3] - w[2] + 1), w[0], w[1], 1, n, 1);
                update(((double)w[3] - w[2]) / ((double)w[3] - w[2] + 1), c2 / ((double)w[1] - w[0] + 1), w[2], w[3], 1, n, 1);
            } else {
                printf("%.8f
    ", query(w[0], w[1], 1, n, 1));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    支付功能测试用例设计要点
    接口测试用例设计实践总结
    如何高效学习
    性能测试基础总结和自己的理解
    linux安装AWStats业务数据分析工具
    python3登陆接口测试
    Python2和Python3中urllib库中urlencode的使用注意事项
    运用BT在centos下搭建一个博客论坛
    python环境搭建-requests的简单安装(适合新手)
    web 资源好文
  • 原文地址:https://www.cnblogs.com/ftae/p/8005682.html
Copyright © 2011-2022 走看看