题目
满足单点修改和区间查询方差
分析
我的题解已经说的比较清楚了,只需要维护区间和以及区间平方和,由于数据比较水,所以说可以用树状数组维护,然后再用逆元求解
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long ll;
const ll mod=1000000007;
ll n,a[100001],b[100001],m;
inline ll inv(ll x){
if (x<2) return x;
return (mod-mod/x)*inv(mod%x)%mod;
}
inline ll p(ll x){return x*x;}
inline ll iut(){
rr ll ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void add1(ll x,ll t){while (x<=n) a[x]=(a[x]+t)%mod,x+=-x&x;}
inline void add2(ll x,ll t){while (x<=n) b[x]=(b[x]+t)%mod,x+=-x&x;}
inline ll ask1(ll x){
rr ll ans=0;
while (x) ans=(ans+a[x])%mod,x-=-x&x;
return ans;
}
inline ll ask2(ll x){
rr ll ans=0;
while (x) ans=(ans+b[x])%mod,x-=-x&x;
return ans;
}
inline void print(ll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
signed main(){
n=iut(); m=iut();
for (rr ll i=1;i<=n;++i) a[i]=(a[i-1]+iut())%mod,b[i]=(b[i-1]+p(a[i]-a[i-1]))%mod;
for (rr ll i=n;i>=1;--i) a[i]-=a[i-(-i&i)],b[i]-=b[i-(-i&i)];
while (m--){
rr ll q=iut(),l=iut(),r=iut();
if (q==1) add1(l,r-ask1(l)+ask1(l-1)),add2(l,r*r-ask2(l)+ask2(l-1));
else if (l==r) putchar(48),putchar(10);
else{
rr ll ans=((ask2(r)-ask2(l-1))*(r-l+1)%mod-p((ask1(r)-ask1(l-1))%mod))%mod;
ans=(ans+mod)*inv(p(r-l+1)%mod)%mod;
print(ans); putchar(10);
}
}
return 0;
}
···