• CSUSTOJ 1127-区间方差(线段树)


    题目链接:http://acm.csust.edu.cn/problem/1127
    CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/108026329

    Description

    线段树进阶题

    n个数m次操作1 pos x 将位置为pos的值修改为x

    2 l r 查询区间l,r的方差乘以区间长度的平方

    Input
    输入:第一行,n,m

    接下来一行n个数接下来m行操作

    (1 pos x 2 l r(1 leq n, m leq 2^{16})(0leq aileq 10^4))

    Output
    输出每次询问的值

    Sample Input 1
    4 4
    1 2 3 4
    2 1 4
    1 2 4
    2 1 4
    2 2 4

    Sample Output 1
    20
    24
    2

    emmm,题面有点难看。。。可能是当时出题人还不太会Markdown吧。

    我们可以先写出它要用的公式:(S^2=frac{sum_{i=l}^r(a_i-ar{a})^2}{r-l+1} imes (r-l+1)^2)
    接下来我们就是将其化简一波:
    (S^2=sum_{i=l}^r(a_i-ar a)^2 imes L)
    ( =Lsum_{i=l}^ra_i^2+(frac{sum}{L})^2-2a_ifrac{sum}{L})
    ( =sum a_i^2L+sum frac{sum^2}{L}-sum 2a_isum)
    ( =Lsum a_i^2+Lfrac{sum^2}{L}-2sumsum a_i)
    ( =Lsum a_i^2+sum^2-2sum^2)
    ( =Lsum a_i^2-sum^2)

    于是就会发现。。。。这不就是个sb线段树嘛。。。。维护一下区间和,维护一下区间平方和就完事了。

    以下是AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define lc rt<<1
    #define rc rt<<1|1
    typedef long long ll;
    const int mac=1e5+10;
    
    int a[mac];
    ll sum[mac<<2],suma2[mac<<2];
    ll ans1=0,ans2=0;
    
    ll pw2(ll x) {return x*x;}
    
    void push_up(int rt)
    {
    	sum[rt]=sum[lc]+sum[rc];
    	suma2[rt]=suma2[lc]+suma2[rc];
    }
    
    void build(int l,int r,int rt)
    {
    	if (l==r){
    		sum[rt]=a[l];
    		suma2[rt]=pw2(a[l]);
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(lson); build(rson);
    	push_up(rt);
    }
    
    void update(int l,int r,int rt,int pos,int val)
    {
    	if (l==r){
    		sum[rt]=val;
    		suma2[rt]=pw2(val);
    		return;
    	}
    	int mid=(l+r)>>1;
    	if (mid>=pos) update(lson,pos,val);
    	else update(rson,pos,val);
    	push_up(rt);
    }
    
    void query(int l,int r,int rt,int L,int R)
    {
    	if (l>=L && r<=R){
    		ans1+=suma2[rt];
    		ans2+=sum[rt];
    		return;
    	}
    	int mid=(l+r)>>1;
    	if (mid>=L) query(lson,L,R);
    	if (mid<R) query(rson,L,R);
    }
    
    int main(int argc, char const *argv[])
    {
    	int n,m;
    	scanf ("%d%d",&n,&m);
    	for (int i=1; i<=n; i++) scanf ("%d",&a[i]);
    	build(1,n,1);
    	for (int i=1; i<=m; i++){
    		int opt,l,r,pos,x;
    		scanf ("%d",&opt);
    		if (opt==1){
    			scanf ("%d%d",&pos,&x);
    			update(1,n,1,pos,x);
    		}
    		else {
    			scanf ("%d%d",&l,&r);
    			if (l==r) {printf("0
    "); continue;}
    			ans1=0; ans2=0;
    			query(1,n,1,l,r);
    			printf("%lld
    ",(r-l+1)*ans1-pw2(ans2));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    [C#.net]获取文本文件的编码,自动区分GB2312和UTF8
    [C#.net]SqlDataAdapter 执行超时已过期 完成操作之前已超时或服务器未响应
    [C#.Net]Window服务调用外部程序
    [Bat]UNC路径不支持的2种解决方法
    [c#.net]未能加载文件或程序集“”或它的某一个依赖项。系统找不到指定的文件
    精读比特币论文
    动态添加Redis密码认证
    扫码登录的安全性分析
    Cookie与Passport安全
    Http压测工具wrk使用指南
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13509886.html
Copyright © 2020-2023  润新知