10pts求调
查看原帖
10pts求调
586932
White_Wat楼主2024/1/24 22:24
#include<iostream>

using namespace std;

#define N 100010

int n,m;
long long a[N];
long long sum[N*4],ssum[N*4];
long long mod=1e9+7;

long long inv(long long x,long long p)
{
	long long ans=1;
	while(p)
	{
		if(p&1) ans=ans*x;
		ans%=mod;
		x*=x;
		x%=mod;
		p>>=1;
	}
	return ans;
}

void build(int l,int r,int p)
{
	if(l==r)
	{
		sum[p]=(a[l])%mod;
		ssum[p]=(a[l]*a[l])%mod;
		return ;
	}
	int mid=(l+r)>>1;
	build(l,mid,p*2);
	build(mid+1,r,p*2+1);
	sum[p]=(sum[p*2]+sum[p*2+1])%mod;
	ssum[p]=(ssum[p*2]+ssum[p*2+1])%mod;
}
void change(int l,int r,int s,int t,int p,long long k)
{
	if(l<=s&&t<=r)
	{
		sum[p]=k;
		ssum[p]=(k*k)%mod;
		return ;
	}
	int mid=(s+t)>>1;
	if(l<=mid) change(l,r,s,mid,p*2,k);
	if(r>mid) change(l,r,mid+1,t,p*2+1,k);
	sum[p]=(sum[p*2]+sum[p*2+1])%mod;
	ssum[p]=(ssum[p*2]+ssum[p*2+1])%mod;
}
long long get_sum(int l,int r,int s,int t,int p)
{
	if(l<=s&&t<=r)
	{
		return sum[p];
	}
	int mid=(s+t)>>1;
	long long su=0;
	if(l<=mid) su=get_sum(l,r,s,mid,p*2);
	if(r>mid) su+=get_sum(l,r,mid+1,t,p*2+1);
	return su%mod;
}
long long get_ssum(int l,int r,int s,int t,int p)
{
	if(l<=s&&t<=r)
	{
		return ssum[p];
	}
	int mid=(s+t)>>1;
	long long su=0;
	if(l<=mid) su=get_ssum(l,r,s,mid,p*2);
	if(r>mid) su+=get_ssum(l,r,mid+1,t,p*2+1);
	return su%mod;
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	build(1,n,1);
	for(int i=1;i<=m;i++)
	{
		int opt;
		long long x,y;
		cin>>opt>>x>>y;
		if(opt==1)
		{
			change(x,x,1,n,1,y);
		}
		else if(opt==2)
		{
			long long su=get_sum(x,y,1,n,1),ssu=get_ssum(x,y,1,n,1);
			long long nn=inv(y-x+1,mod-2)%mod,ave=su*nn%mod;
			printf("%lld\n",((ssu-((2*ave*su)%mod)+((((y-x+1)*ave)*ave)%mod)+mod)*nn%mod+mod)%mod);
		}
	}
	return 0;
}
2024/1/24 22:24
加载中...