• [CF895E]Eyes Closed


    luogu

    description

    一个序列(a_i),支持一下两种操作。
    (1 l_1 r_1 l_2 r_2): 随机交换区间([l_1,r_1])([l_2,r_2])中的两个值。
    (2 l r):查询(sum_{i=l}^ra_i)的期望。

    sol

    设两个交换区间的和分别是(s_1,s_2),长度分别是(len_1,len_2)
    考虑区间([l_1,r_1])中的一个元素(x),在交换后它的期望值会变为:
    (frac{len_1-1}{len_1}x+frac{1}{len_1} imesfrac{s_2}{len_2})
    区间([l_2,r_2])中的数同理,会变成:
    (frac{len_2-1}{len_2}x+frac{1}{len_2} imesfrac{s_1}{len_1})
    所以线段树支持区间加区间乘区间求和即可。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 2e5+5;
    int n,m;double sum[N<<2],pls[N<<2],mul[N<<2];
    void build(int x,int l,int r){
    	if (l==r) {sum[x]=gi();return;}
    	int mid=l+r>>1;mul[x]=1;
    	build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    void cover_pls(int x,int l,int r,double v){
    	sum[x]+=v*(r-l+1);pls[x]+=v;
    }
    void cover_mul(int x,double v){
    	sum[x]*=v;mul[x]*=v;pls[x]*=v;
    }
    void pushdown(int x,int l,int r){
    	int mid=l+r>>1;
    	cover_mul(x<<1,mul[x]),cover_mul(x<<1|1,mul[x]);
    	cover_pls(x<<1,l,mid,pls[x]),cover_pls(x<<1|1,mid+1,r,pls[x]);
    	pls[x]=0;mul[x]=1;
    }
    void modify_pls(int x,int l,int r,int ql,int qr,double v){
    	if (l>=ql&&r<=qr) {cover_pls(x,l,r,v);return;}
    	pushdown(x,l,r);int mid=l+r>>1;
    	if (ql<=mid) modify_pls(x<<1,l,mid,ql,qr,v);
    	if (qr>mid) modify_pls(x<<1|1,mid+1,r,ql,qr,v);
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    void modify_mul(int x,int l,int r,int ql,int qr,double v){
    	if (l>=ql&&r<=qr) {cover_mul(x,v);return;}
    	pushdown(x,l,r);int mid=l+r>>1;
    	if (ql<=mid) modify_mul(x<<1,l,mid,ql,qr,v);
    	if (qr>mid) modify_mul(x<<1|1,mid+1,r,ql,qr,v);
    	sum[x]=sum[x<<1]+sum[x<<1|1];
    }
    double query(int x,int l,int r,int ql,int qr){
    	if (l>=ql&&r<=qr) return sum[x];
    	pushdown(x,l,r);int mid=l+r>>1;double res=0;
    	if (ql<=mid) res+=query(x<<1,l,mid,ql,qr);
    	if (qr>mid) res+=query(x<<1|1,mid+1,r,ql,qr);
    	return res;
    }
    int main(){
    	n=gi();m=gi();build(1,1,n);
    	while (m--){
    		int opt=gi();
    		if (opt==1){
    			int a=gi(),b=gi(),c=gi(),d=gi();
    			double l1=b-a+1,l2=d-c+1;
    			double s1=query(1,1,n,a,b),s2=query(1,1,n,c,d);
    			modify_mul(1,1,n,a,b,(l1-1)/l1);
    			modify_mul(1,1,n,c,d,(l2-1)/l2);
    			modify_pls(1,1,n,a,b,1.0/l1*(s2/l2));
    			modify_pls(1,1,n,c,d,1.0/l2*(s1/l1));
    		}else{
    			int a=gi(),b=gi();
    			printf("%.5lf
    ",query(1,1,n,a,b));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    maven创建父子工程
    webservice之jersey简单实用
    EL表达式处理字符串
    oracle不等于1怎么查?
    day_07 搭建Tomcat服务器使用Servlet服务,后端接受前端请求过来的表单数据并使用
    Day_06 流程控制-循环结构-嵌套循环结构的原理解析
    Day05_流程控制02 循环结构
    day_5 流程控制 选择结构的两种常用语句的使用语法
    day_04 运算符详解
    day_03 变量的数据类型详解
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9200883.html
Copyright © 2020-2023  润新知