zoukankan      html  css  js  c++  java
  • 895E

    考虑左区间中的任意数x,令len1为左区间长度,sum1为左区间的期望和

    经过操作1,x的期望会变为x*(len1-1)/len1+sum2/len2*(1/len1)

    这个变化相当于y=kx+b,因此可以用线段树维护乘法和加法

    要注意的是pushdown的时候子节点的加法受到父节点乘法的影响

    #include<bits/stdc++.h>    
    //#pragma comment(linker, "/STACK:1024000000,1024000000")     
    #include<stdio.h>    
    #include<algorithm>    
    #include<queue>    
    #include<string.h>    
    #include<iostream>    
    #include<math.h>    
    #include<set>    
    #include<map>    
    #include<vector>    
    #include<iomanip>    
    using namespace std;    
    #define ll long long    
    #define pb push_back    
    #define FOR(a) for(int i=1;i<=a;i++)   
    #define sqr(a) (a)*(a)  
      
    const int inf=0x3f3f3f3f;  
    const int maxn=1e6+5;  
    const int mod=1e9+7;  
      
    struct NODE{
    	double sum,add,mul;
    }ST[maxn<<2];
    
    void pushup(int rt){
    	ST[rt].sum=ST[rt<<1].sum+ST[rt<<1|1].sum;
    }
    void pushdown(int l,int r,int rt){
    	int m=l+r>>1;
    	ST[rt<<1].sum=ST[rt].mul*ST[rt<<1].sum+(m-l+1)*ST[rt].add;
    	ST[rt<<1].mul*=ST[rt].mul;
    	ST[rt<<1].add=ST[rt].mul*ST[rt<<1].add+ST[rt].add;
    	ST[rt<<1|1].sum=ST[rt].mul*ST[rt<<1|1].sum+(r-m)*ST[rt].add;
    	ST[rt<<1|1].mul*=ST[rt].mul;
    	ST[rt<<1|1].add=ST[rt].mul*ST[rt<<1|1].add+ST[rt].add;
    	ST[rt].add=0;ST[rt].mul=1;
    }
    void build(int l,int r,int rt){
    	ST[rt].sum=ST[rt].add=0;ST[rt].mul=1;
    	if(l==r){scanf("%lf",&ST[rt].sum);return;}
    	int m=l+r>>1;
    	build(l,m,rt<<1);build(m+1,r,rt<<1|1);pushup(rt);
    }
    void update_mul(int a,int b,double c,int l,int r,int rt){
    	if(a<=l&&b>=r){
    		ST[rt].sum*=c;ST[rt].mul*=c;ST[rt].add*=c;return;	
    	}
    	pushdown(l,r,rt);
    	int m=l+r>>1;
    	if(a<=m)update_mul(a,b,c,l,m,rt<<1);
    	if(b>m)update_mul(a,b,c,m+1,r,rt<<1|1);
    	pushup(rt);
    }
    void update_add(int a,int b,double c,int l,int r,int rt){
    	if(a<=l&&b>=r){
    		ST[rt].add+=c;ST[rt].sum+=(r-l+1)*c;return;
    	}
    	pushdown(l,r,rt);
    	int m=l+r>>1;
    	if(a<=m)update_add(a,b,c,l,m,rt<<1);
    	if(b>m)update_add(a,b,c,m+1,r,rt<<1|1);
    	pushup(rt);
    }
    double query(int a,int b,int l,int r,int rt){
    	if(a<=l&&b>=r){return ST[rt].sum;}
    	int m=l+r>>1;
    	pushdown(l,r,rt);
    	double ans=0;
    	if(a<=m)ans+=query(a,b,l,m,rt<<1);
    	if(b>m)ans+=query(a,b,m+1,r,rt<<1|1);
    	return ans;
    }
    
    int main(){
    	int n,q;scanf("%d%d",&n,&q);
    	build(1,n,1);
    	for(int i=1;i<=q;i++){
    		int op;scanf("%d",&op);
    		if(op==1){
    			int l1,r1,l2,r2;scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
    			double sum1=query(l1,r1,1,n,1),sum2=query(l2,r2,1,n,1);
    			double len1=r1-l1+1,len2=r2-l2+1;
    			update_mul(l1,r1,(len1-1)/len1,1,n,1);
    			update_mul(l2,r2,(len2-1)/len2,1,n,1);
    			update_add(l1,r1,1.0/len1*sum2/len2,1,n,1);
    			update_add(l2,r2,1.0/len2*sum1/len1,1,n,1);
    		}else{
    			int l,r;scanf("%d%d",&l,&r);
    			printf("%.7lf
    ",query(l,r,1,n,1));
    		}
    	}
    }


  • 相关阅读:
    Variable() placeholder() constant() 的区别
    scrapy-redis+selenium+webdriver 部署到linux上
    scrapy-redis+selenium+webdriver解决动态代理ip和user-agent的问题(全网唯一完整代码解决方案)
    [学习记录]NLTK常见操作二(分句,分词,词干提取)
    [学习记录]NLTK常见操作一(去网页标记,统计词频,去停用词)
    [学习记录]python正则表达式
    [学习记录]MySQL之初级查询语句(select,where)
    [学习记录]pymysql的基本操作
    [学习记录]MySQL临时整理
    [学习记录]面对wxpython的长跑(100米:wxpython安装,相关文件,wx.App,wx.Frame)
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611203.html
Copyright © 2011-2022 走看看