树状数组 30 pts 求助
  • 板块P5142 区间方差
  • 楼主wdgm4
  • 当前回复7
  • 已保存回复7
  • 发布时间2023/7/11 20:29
  • 上次更新2023/11/3 10:27:29
查看原帖
树状数组 30 pts 求助
555950
wdgm4楼主2023/7/11 20:29
#include<bits/stdc++.h>
#define XD 114514
#define MAXN 100010
#define int long long
#define lowbit(x) x&-x
using namespace std;
const int mod=1000000007;
int n,m,a[MAXN];
int t[MAXN],t2[MAXN];
void add(int x,int y){
	for(int i=x;i<=n;i+=lowbit(i)) t[i]=((t[i]+y)%mod+mod)%mod;
	for(int i=x;i<=n;i+=lowbit(i)) t2[i]=((t2[i]+y*y%mod)%mod+mod)%mod;
}
int query(int x){
	int nem=0;
	for(int i=x;i;i-=lowbit(i)) nem=(nem+t[i])%mod;
	return nem;
}
int query2(int x){
	int nem=0;
	for(int i=x;i;i-=lowbit(i)) nem=((nem+t2[i])%mod+mod)%mod;
	return nem;
}
int times(int x,int y){
	int ans=1;
	while(y){
		if(y&1ll) ans=ans*x%mod;
		x=x*x%mod;
		y>>=1ll;
	}
	return ans;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		add(i,a[i]);
	} 
	while(m--){
		int opt;cin>>opt;
		if(opt==1){
			int x,y;cin>>x>>y;
			add(x,-a[x]);
			add(x,y);
			a[x]=y;
		}else{
			int l,r;cin>>l>>r;
			int len=r-l+1;
			//frac{xn-y^2}{n^2} x=\sum_{i=1}^n a_i^2 y=\sum_{i=1}^n a_i
			int x=((query2(r)-query2(l-1))%mod+mod)%mod;
			int y=((query(r)-query(l-1))%mod+mod)%mod;
			int nem1=x*len%mod,nem2=y*y%mod;
			int up=((nem1-nem2)%mod+mod)%mod,down=len*len%mod;
			cout<<(up*times(down%mod,mod-2)%mod)<<"\n";
		}
	}
	return 0;
}

2023/7/11 20:29
加载中...