zoukankan      html  css  js  c++  java
  • 期望线性性+线段树双tag标记——cf895E

    /*
    从区间[l1,r1]取出一个数,这个数的期望值为 e1=(sum[r1]-sum[l1-1])/(r1-l1+1)
    同理从区间[l2,r2]里取出一个数,这个数期望为 e2=(sum[r2]-sum[l2-1])/(r2-l2+1)
    根据期望线性性,[l1,r1]里每个数被选中的概率是1/len1
              所以一次交换后该区间的a[i] ->  (len1-1)/len1*a[i]+1/len1*e2
              同理[l2,r2]里的 a[i] -> (len2-1)/len2*a[i]+1/len2*e1 
    用一个线段树来维护sum,两个tag:mul和add 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 200005
    
    int n,a[N],q; 
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    double sum[N<<2],mul[N<<2],add[N<<2];
    void pushdown(int l,int r,int rt){
        int m=l+r>>1;
        sum[rt<<1]*=mul[rt];sum[rt<<1]+=(m-l+1)*add[rt];
        sum[rt<<1|1]*=mul[rt];sum[rt<<1|1]+=(r-m)*add[rt];
        mul[rt<<1]*=mul[rt];
        mul[rt<<1|1]*=mul[rt];
        add[rt<<1]*=mul[rt];add[rt<<1]+=add[rt];
        add[rt<<1|1]*=mul[rt];add[rt<<1|1]+=add[rt];
        mul[rt]=1;add[rt]=0;
    }
    void build(int l,int r,int rt){
        mul[rt]=1;add[rt]=0;
        if(l==r){sum[rt]=a[l];return;}
        int m=l+r>>1;
        build(lson);build(rson);
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void update(int L,int R,double MUL,double ADD,int l,int r,int rt){
        if(L<=l && R>=r){
            sum[rt]*=MUL;sum[rt]+=ADD*(r-l+1);
            mul[rt]*=MUL;
            add[rt]*=MUL;add[rt]+=ADD;
            return;
        }
        pushdown(l,r,rt);
        int m=l+r>>1;
        if(L<=m)update(L,R,MUL,ADD,lson);
        if(R>m)update(L,R,MUL,ADD,rson);
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    double query(int L,int R,int l,int r,int rt){
        if(L<=l && R>=r)return sum[rt];
        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(){
        cin>>n>>q;
        for(int i=1;i<=n;i++)cin>>a[i];
        build(1,n,1);
        while(q--){
            int op,l1,l2,r1,r2,len1,len2;
            cin>>op;
            if(op==2){
                scanf("%d%d",&l1,&r1);
                cout<<query(l1,r1,1,n,1)<<'
    ';
            }
            else {
                scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
                len1=r1-l1+1;
                len2=r2-l2+1;
                double sum1=query(l1,r1,1,n,1);
                double sum2=query(l2,r2,1,n,1);
                double e1=sum1/len1;
                double e2=sum2/len2;
                double mul1=1.0*(len1-1)/len1;
                double mul2=1.0*(len2-1)/len2;
                double add1=1.0/len1*e2;
                double add2=1.0/len2*e1;
                update(l1,r1,mul1,add1,1,n,1);
                update(l2,r2,mul2,add2,1,n,1);
            }
        }
        
    } 
  • 相关阅读:
    uva111 History Grading
    UVA 10100Longest Match
    UVA 147Dollars
    归并排序模板
    找礼物(find)
    水流(water)dfs
    细菌(disease) 位运算
    单词接龙
    关于jquery的each遍历,return只终止当前循环,不好使的解决办法
    jquery中ajax回调函数使用this
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12295902.html
Copyright © 2011-2022 走看看