这题是不是不能用带修莫队?写了一发但开O2还T三个点,两个都是1.20s满时限T的
或者是我的带修出问题了?
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 100010
#define ll long long
const ll p=1000000007;
int n,m;
ll an[N],sz,a[N],s2,s;
class query{
public:
ll l,r,t,id;
bool operator <(query x)const{
if(l/sz==x.l/sz){
if(r/sz==x.r/sz)return t<x.t;
else return r<x.r;
}else return l<x.l;
}
}q[N];
class changing{
public:
int p;
ll v,lst;
}op[N];
void add(ll v){
s2=(s2+v*v%p);
s=(s+v%p)%p;
return;
}void del(ll v){
s2=(s2-v*v%p+p)%p;
s=(s-v%p+p)%p;
return;
}void Do(int k,int l,int r){
int p=op[k].p;
op[k].lst=a[p];
a[p]=op[k].v;
if(p<=r&&p>=l)del(op[k].lst),add(op[k].v);
return;
}void Redo(int k,int l,int r){
int p=op[k].p;
op[k].v=a[p];
a[p]=op[k].lst;
if(p<=r&&p>=l)del(op[k].v),add(op[k].lst);
}ll fpow(ll a,ll x){
if(x==0)return 1;
ll r=fpow(a,x/2);
if(x&1)return r*r%p*a%p;
else return r*r%p;
}
int main(){
freopen("data.in","r",stdin);
freopen("my.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
int que=0,tm=0;
for(int i=1;i<=m;i++){
int c,x,y;
scanf("%d%d%d",&c,&x,&y);
if(c==1)op[++tm]=(changing){x,y,0};
else q[++que]=(query){x,y,tm,que};
}if(tm==0)tm=1;
sz=std::pow(tm*n,0.3333);
std::sort(q+1,q+que+1);
int l=1,r=0,t=0;
for(int i=1;i<=que;i++){
while(l<q[i].l)del(a[l++]);
while(l>q[i].l)add(a[--l]);
while(r<q[i].r)add(a[++r]);
while(r>q[i].r)del(a[r--]);
while(t<q[i].t)Do(++t,l,r);
while(t>q[i].t)Redo(t--,l,r);
ll len=r-l+1;
an[q[i].id]=(len*s2%p-s*s%p+p)%p*fpow(len*len%p,p-2)%p;
}for(int i=1;i<=que;i++)printf("%lld\n",an[i]);
return 0;
}