蒟蒻线段树10pts求助
查看原帖
蒟蒻线段树10pts求助
648772
Liyuqiao11楼主2023/11/7 09:29
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10,md=1e9+7;
int n,m,a[N];
struct T{
    int l;
    int r;
    int sum;
    int num;
    int lazy;
}t[N*4];
int qpow(int x,int y){
    if(y==1){
        return x%md;
    }
    int dc=qpow(x,y/2);
    if(y%2==1){
        return dc%md*dc%md*qpow(x,1);
    }
    else return dc%md*dc%md;
}
void pushup(int i){
    t[i].sum=t[i*2].sum%md+t[i*2+1].sum%md;
    t[i].num=t[i*2].num%md+t[i*2+1].num%md;
}
void pushdown(int i){
    if(t[i].lazy==0) return;
    if(t[i].l==t[i].r){
        t[i].lazy=0;
        return;
    }
    t[i*2].lazy+=t[i].lazy%md;
    t[i*2+1].lazy+=t[i].lazy%md;
    t[i*2].num+=t[i*2].sum*t[i].lazy*2+t[i].lazy*t[i].lazy*(t[i*2].r-t[i*2].l+1);
    t[i*2].num%=md;
    t[i*2+1].num+=t[i*2+1].sum*t[i].lazy*2+t[i].lazy*t[i].lazy*(t[i*2+1].r-t[i*2+1].l+1);
    t[i*2+1].num%=md;
    t[i*2].sum+=(t[i*2].r-t[i*2].l+1)*t[i].lazy;
    t[i*2].sum%=md;
    t[i*2+1].sum+=(t[i*2+1].r-t[i*2+1].l+1)*t[i].lazy;
    t[i*2+1].sum%=md;
    t[i].lazy=0;
}
void build(int i,int l,int r){
    t[i].l=l;
    t[i].r=r;
    if(l==r){
        t[i].sum=a[l]%md;
        t[i].num=(a[l]%md*a[l]%md)%md;
        return;
    }
    int mid=(l+r)/2;
    build(i*2,l,mid);
    build(i*2+1,mid+1,r);
    pushup(i);
}
void update(int i,int l,int r,int x){
    pushdown(i);
    if(t[i].l>=l&&t[i].r<=r){
        t[i].lazy=x%md;
        t[i].num=(x%md*x%md*(t[i].r-t[i].l+1)%md)%md;
        t[i].sum=((t[i].r-t[i].l+1)%md*x%md)%md;
        return;
    }
    if(t[i*2].r>=l){
        update(i*2,l,r,x);
    }
    if(t[i*2+1].l<=r){
        update(i*2+1,l,r,x);
    }
    pushup(i);
}
int query(int i,int l,int r){
    pushdown(i);
    int ans=0;
    if(t[i].l>=l&&t[i].r<=r){
        return t[i].sum%md;
    }
    if(t[i*2].r>=l){
        ans=(ans+query(i*2,l,r))%md;
    }
    if(t[i*2+1].l<=r){
        ans=(ans+query(i*2+1,l,r))%md;
    }
    return ans%md;
}
int query2(int i,int l,int r){
    pushdown(i);
    int ans=0;
    if(t[i].l>=l&&t[i].r<=r){
        return t[i].num%md;
    }
    if(t[i*2].r>=l){
        ans=(ans+query2(i*2,l,r))%md;
    }
    if(t[i*2+1].l<=r){
        ans=(ans+query2(i*2+1,l,r))%md;
    }
    return ans%md;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    int op;
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>op;
        if(op==1){
            cin>>x>>y;
            update(1,x,x,y%md);
        }
        if(op==2){
            cin>>x>>y;
            int dc=query2(1,x,y)%md,f=query(1,x,y)%md;
            int q=qpow((y-x+1),md-2);
            int av=f*q%md;
            int ans=dc*q%md-av*av%md;
            ans=(ans%md+md)%md;
            cout<<ans<<endl;
            //cout<<dc<<" "<<f<<endl;
        }
    }
    return 0;
}
2023/11/7 09:29
加载中...