luogu P5142 区间方差 十分优美的线段树

又来了个维护方差的线段树。。。。

大致推导过程(字丑多包涵QAQ)

注意取模时要加一些100000007防止出现负数。。

#include<cstdio>
#include<iostream>
#define ll long long
#define R register long long
#define ls (tr<<1)
#define rs (tr<<1|1)
using namespace std;
const long long M=1000000007;
int n,m;
inline ll g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
ll sum[400010],po[400010];
void build(int tr,int l,int r) {
    if(l==r) {sum[tr]=g(),po[tr]=sum[tr]*sum[tr]; return;}
    R md=(l+r)>>1;
    build(ls,l,md),build(rs,md+1,r);
    sum[tr]=sum[ls]+sum[rs],po[tr]=po[ls]+po[rs];
}
void add(int tr,int l,int r,int pos,ll d) {
    if(l==r) {sum[tr]=d%M; po[tr]=d*d%M; return ;}
    R md=(l+r)>>1;
    if(pos>md) add(rs,md+1,r,pos,d);
    else if(pos<md+1) add(ls,l,md,pos,d);
    sum[tr]=(sum[ls]+sum[rs])%M,po[tr]=(po[ls]+po[rs])%M;
}
ll query(int tr,int l,int r,int LL,int RR) {
    if(l==LL&&r==RR) return sum[tr];
    R md=(l+r)>>1;
    if(LL>md) return query(rs,md+1,r,LL,RR);
    else if(RR<md+1) return query(ls,l,md,LL,RR);
    else return (query(ls,l,md,LL,md)+query(rs,md+1,r,md+1,RR))%M;
}
ll _query(int tr,int l,int r,int LL,int RR) {
    if(l==LL&&r==RR) return po[tr];
    R md=(l+r)>>1;
    if(LL>md) return _query(rs,md+1,r,LL,RR);
    else if(RR<md+1) return _query(ls,l,md,LL,RR);
    else return (_query(ls,l,md,LL,md)+_query(rs,md+1,r,md+1,RR))%M;
}
inline ll qpow(int a) {
    R ret=1,p=M-2; a%=M;
    for(;p;p>>=1,(a*=a)%=M) if(p&1) (ret*=a)%=M;
    return ret;
}
inline ll Inv(int x) {
    if(x==1) return 1; if(x<1) return 0;
    return (M-M/x)*Inv(M%x)%M;
}
signed main() {
    n=g(),m=g();
    build(1,1,n);
    for(R i=1;i<=m;++i) {
        R k=g(),l=g(),r=g();
        if(k&1) add(1,1,n,l,r);
        else {
            R inv=Inv(r-l+1),ave=query(1,1,n,l,r)*inv%M;
            printf("%lld\n",((_query(1,1,n,l,r)%M-(ave<<1)*query(1,1,n,l,r)%M+M)*inv%M+ave*ave%M+M)%M);
        }
    }
}

也可树状数组,就不多说了(自己没写)(怕是树状数组更易写?)


 

2019.04.12

posted @ 2019-04-12 00:30  LuitaryiJack  阅读(251)  评论(0编辑  收藏  举报