zoukankan      html  css  js  c++  java
  • [线段树]JZOJ 4231 寻找神格

    Description

     淬炼完神体,王仙女被传送到了遥远处一座没有神雷的浮岛上,发现浮岛上除了一扇门以外什么都没有。他来到门前,发现上面写着这样一段话:
    一个神出了拥有强大的神体外,还需要一枚神格。然而,想要获得神格没那么简单,除了有实力外还需要有运气。曾经有一个人叫金(jin)字(zi)塔(da),他的神体很强,很壮,可是他根本没有运气,所以最后神格拒绝了他。打开这扇门,你将会进入一个神格创造的空间,在那里,神格将会问你一些问题来测试你解决问题的能力,当然,它的问题将会很难,在你答不出来的时候你可以选择随便猜一个答案,以此来展现你的运气。
    王仙女二话不说打开了那扇门,一阵眩晕过后,他来到了一个灰蒙蒙的空间。一个苍老的声音在四周响起:小娃娃,我是一枚存在亿万年的神格,我的上一任主人已经死去百万余年了,我也已经在这里等待了百万年了。能否成为我的主人,让我重现百万年前的风采,就看你的能力和运气了。再问问题之前,我要先跟你讲一件事。成为一个神后,最大的责任便是保护神界的人民,他们都出生在神界,但并不都具有神的实力。当然,神界人族的内部也有战争,他们一共分为N个部落,每两个部落之间都有可能发生战争。为了不然神界人族因为战争而损失惨重,神界的诸神将这些部落编号为1~N,当这些部落的人数差距太大时,诸神便会降临,将一些部落的人带走,并放一些在别的部落中。而衡量所有部落人数差距的数值便是方差。接下来,我会告诉你一些部落的人数增加或减少的信息,并会不时的询问你编号为L~R的部落的总人数或是他们部落人数的方差。
     

    Input

    第一行包含两个正整数N,Q,表示部落数和神格的信息数与询问数总和。
    第二行包含N个数,第i个数a_i表示编号为i的部落最初的人数。
    接下来Q行,第一个数为t。
    当t=0时,这一行还有两个数a,b,表示编号为a的部落增加了b个人(如果b<0则表示减少了|b|个人)。
    当t=1时,这一行还有三个数a,b,c,表示编号为a~b的部落增加了c个人(如果c<0则表示减少了|c|个人)。
    当t=2时,这一行还有两个数a,b,表示神格询问了编号为a~b的部落现在的总人数。
    当t=3时,这一行还有两个数a,b,表示神格询问了编号为a~b的部落人数的方差。

    Output

    对于每个t=2,输出一行,包含一个整数,表示总人数。
    对于每个t=3,输出一行,包含一个实数,表示方差,结果保留三位小数。
     

    Sample Input

    5 5
    1 2 3 4 5
    0 3 3
    1 2 3 6
    2 3 5
    0 1 2
    3 1 5

    Sample Output

    21
    10.640
     

    Data Constraint

    对于30%的数据,N≤1000,Q≤1000
    对于100%的数据,1≤N≤100000,1≤Q≤100000,|a_i |≤1000,数据保证在任何时候|所有部落总人数|≤〖10〗^9
    注:由于神界人族的人数统计是用实际人数减去一个标准值,所以人数可能会出现负数
     

    Hint

    方差的定义:
    求N个数的方差,设这N个数的平均数为ave,第i个数为x_i
    方差=1/n[(x_1-ave)^2+(x_2-ave)^2+⋯+(x_(n-1)-ave)^2+(x_n-ave)^2]

    分析

    修仙小说即视感

    以前写过类似的题解,这是传送门

    精度有问题,SPJ没有说明,需要输出超过3位小数

    #include <iostream>
    #include <cstdio>
    #define lson x<<1
    #define rson (x<<1)+1
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    struct Seg {
        int l,r;
        double sum,msum,lz;
    }t[4*N];
    int a[N];
    int n,q;
    double ans1,ans2;
    
    void Pushdown(int x) {
        if (!x||!t[x].lz) return;
        t[lson].lz+=t[x].lz;t[lson].msum+=(t[lson].r-t[lson].l+1.0)*t[x].lz*t[x].lz+2.0*t[x].lz*t[lson].sum;
        t[lson].sum+=(t[lson].r-t[lson].l+1.0)*t[x].lz;
        t[rson].lz+=t[x].lz;t[rson].msum+=(t[rson].r-t[rson].l+1.0)*t[x].lz*t[x].lz+2.0*t[x].lz*t[rson].sum;
        t[rson].sum+=(t[rson].r-t[rson].l+1.0)*t[x].lz;
        t[x].lz=0;
    }
    
    void Build(int x,int l,int r) {
        t[x].l=l;t[x].r=r;
        if (l==r) {
            t[x].sum=a[l];t[x].msum=1.0*a[l]*a[l];
            return;
        }
        int mid=l+r>>1;
        Build(lson,l,mid);Build(rson,mid+1,r);
        t[x].msum=t[lson].msum+t[rson].msum;
        t[x].sum=t[lson].sum+t[rson].sum;
    }
    
    void Change(int x,int l,int r,int xl,int xr,int b) {
        if (l>xr||xl>r||l>r) return;
        if (xl<=l&&r<=xr) {
            t[x].msum+=(r-l+1.0)*b*b+2.0*b*t[x].sum;t[x].sum+=(r-l+1.0)*b;
            t[x].lz+=b;
            return;
        }
        Pushdown(x);
        int mid=l+r>>1;
        if (xl<=mid) Change(lson,l,mid,xl,xr,b);
        if (mid<xr) Change(rson,mid+1,r,xl,xr,b);
        t[x].msum=t[lson].msum+t[rson].msum;
        t[x].sum=t[lson].sum+t[rson].sum;
    }
    
    void Query(int x,int l,int r,int xl,int xr) {
        if (l>xr||xl>r||l>r) return;
        if (xl<=l&&r<=xr) {
            ans1+=t[x].sum;ans2+=t[x].msum;
            return;
        }
        Pushdown(x);
        int mid=l+r>>1;
        if (xl<=mid) Query(lson,l,mid,xl,xr);
        if (mid<xr) Query(rson,mid+1,r,xl,xr);
    }
    
    int main() {
        scanf("%d%d",&n,&q);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        Build(1,1,n);
        for (int i=1;i<=q;i++) {
            int order,l,r,c;
            scanf("%d%d%d",&order,&l,&r);
            if (order==0) Change(1,1,n,l,l,r);
            else if (order==1) scanf("%d",&c),Change(1,1,n,l,r,c);
            else {
                ans1=ans2=0;
                Query(1,1,n,l,r);
                if (order==2) printf("%lld
    ",(ll)ans1);
                else printf("%.10lf
    ",1.0*ans2/(r-l+1.0)-1.0*ans1*ans1/((r-l+1.0)*(r-l+1.0)));
            }
        }
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    读javascript高级程序设计08-引用类型之Global、Math、String
    读javascript高级程序设计07-引用类型、Object、Array
    读javascript高级程序设计06-面向对象之继承
    读javascript高级程序设计05-面向对象之创建对象
    读javascript高级程序设计04-canvas
    读javascript高级程序设计03-函数表达式、闭包、私有变量
    读javascript高级程序设计02-变量作用域
    C#将Word转换成PDF方法总结(基于Office和WPS两种方案)
    【转】 C#中Finally的一个不太常见的用法
    一看就懂的ReactJs入门教程-精华版
  • 原文地址:https://www.cnblogs.com/mastervan/p/10300943.html
Copyright © 2011-2022 走看看