CF895E Eyes Closed (期望)

题目链接
利用期望的线性性质:
\(E(sum) = E(x_l) + E(x_{l+1})+ E(x_{l+2}) +.. E(x_r)\)
然后就考虑对于交换时两个区间元素的改动.
假设这两个区间的长度分别为\(L_1,L_2\),和为\(S_1,S_2\)
那么对于第一个区间元素的期望为.
\(E(x_i) = \dfrac{L_1 - 1}{L_1} * E(x_i) + \dfrac{1}{L_1}*\dfrac{L_2}{S_2}\)
对于第二个区间也是这样.
然后用线段树维护一下就可以了.

#include <iostream>
#include <cstdio>
#define lson now << 1
#define rson now << 1 | 1
const int maxN = 1e5 + 7;

struct Node {
    int l,r;
    double sum,lazy,mul;
}tree[maxN << 2];

inline int read() {
    int x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
    return x * f;
}

void init(int now,int l,int r) {
    tree[now].l = l;tree[now].r = r;
    tree[now].mul = 1;tree[now].lazy = 0;
    return ;
}

void updata(int now) {
    tree[now].sum = tree[lson].sum + tree[rson].sum;
    return;
}

void build(int now,int l,int r) {
    init(now,l,r);
    if(l == r) {
        tree[now].sum = read();
        return;
    }
    int mid = (l + r) >> 1;
    build(lson,l,mid);
    build(rson,mid + 1,r);
    updata(now);
    return ;
}

void work(int now,double lazy,double mul) {
    tree[now].lazy = tree[now].lazy * mul + lazy;
    tree[now].mul = tree[now].mul * mul;
    tree[now].sum = tree[now].sum * mul + lazy * (tree[now].r - tree[now].l + 1);
    return ;
}

void pushdown(int now) {
    work(lson,tree[now].lazy,tree[now].mul);
    work(rson,tree[now].lazy,tree[now].mul);
    tree[now].lazy = 0;tree[now].mul = 1;
    return ;
}

double query(int now,int L,int R) {
    if(tree[now].l >= L && tree[now].r <= R) return tree[now].sum;
    int mid = (tree[now].l + tree[now].r) >> 1;
    double sum = 0;
    if(tree[now].lazy || tree[now].mul != 1) pushdown(now);
    if(mid >= L) sum += query(lson,L,R);
    if(mid < R) sum += query(rson,L,R);
    return sum;
}

void modify(int now,int L,int R,double lazy,double mul) {
    if(tree[now].l >= L && tree[now].r <= R) {
        work(now,lazy,mul);
        return ;
    }
    if(tree[now].lazy || tree[now].mul != 1) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1;
    if(mid >= L) modify(lson,L,R,lazy,mul);
    if(mid < R) modify(rson,L,R,lazy,mul);
    updata(now);
    return ;
}

int main() {
    int n,m;
    n = read();m = read();
    build(1,1,n);
    int opt,l1,r1,l2,r2;
    while(m --) {
        opt = read() - 1;l1 = read();r1 = read();
        if(!opt) {
            l2 = read();r2 = read();
            int L_1,L_2;
            double S_1,S_2;
            L_1 = r1 - l1 + 1;L_2 = r2 - l2 + 1;
            S_1 = query(1,l1,r1);S_2 = query(1,l2,r2);
            modify(1,l1,r1,1.0 / L_1 * S_2 / L_2,1.0 * (L_1 - 1) / L_1);
            modify(1,l2,r2,1.0 / L_2 * S_1 / L_1,1.0 * (L_2 - 1) / L_2);
        }
        else printf("%.7lf\n",query(1,l1,r1));
    }
    return 0;
}
posted @ 2018-09-25 20:42  Rlif  阅读(288)  评论(0编辑  收藏  举报