! BJOI2018链上二次求和
作者:互联网
此题实际就是序列上的问题(只是链的话不一定\(u<v\),判一下)
\(ans=\sum_{i=l}^r\sum_{j=i}^ns_j-s_{j-i}=\sum_{i=l}^r(\sum_{j=i}^ns_j-\sum_{j=0}^{n-i}s_j)\)
改成二维前缀和
\(ans=\sum^r_{i=l}ss_n-ss_{i-1}-ss_{n-i}\)
用线段树维护二维前缀和即可(肯定是一个二次函数,拆开算贡献即可)
时间复杂度\(O(nlog_n)\)
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f==1?x:-x;
}
#define ll long long
#define lc (p<<1)
#define rc (p<<1|1)
const int N=2e5+4,mod=1e9+7,inv2=5e8+4;
int n,m,a[N],la[N<<2],lb[N<<2],le[N<<2],t[N<<2],lza[N<<2],lzb[N<<2],lzc[N<<2];
void build(int p,int l,int r){
le[p]=r-l+1;
if(l==r){
t[p]=a[l];
la[p]=(ll)l*l%mod;
lb[p]=l;
return;
}
int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
t[p]=(t[lc]+t[rc])%mod;
la[p]=(la[lc]+la[rc])%mod;
lb[p]=(lb[lc]+lb[rc])%mod;
}
inline void pushnow(int p,int a,int b,int c){
t[p]=((ll)a*la[p]%mod+(ll)b*lb[p]%mod+(ll)c*le[p]%mod+t[p])%mod;
lza[p]=(lza[p]+a)%mod;lzb[p]=(lzb[p]+b)%mod;lzc[p]=(lzc[p]+c)%mod;
}
inline void pushdown(int p){
if(!lza[p]&&!lzb[p]&&!lzc[p])return;
pushnow(lc,lza[p],lzb[p],lzc[p]);
pushnow(rc,lza[p],lzb[p],lzc[p]);
lza[p]=lzb[p]=lzc[p]=0;
}
void modify(int p,int l,int r,int ql,int qr,int va,int vb,int vc){
if(ql<=l&&r<=qr){
pushnow(p,va,vb,vc);
return;
}
int mid=l+r>>1;
pushdown(p);
if(ql<=mid)modify(lc,l,mid,ql,qr,va,vb,vc);
if(mid<qr)modify(rc,mid+1,r,ql,qr,va,vb,vc);
t[p]=(t[lc]+t[rc])%mod;
}
int query(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return t[p];
int mid=l+r>>1,ret=0;
pushdown(p);
if(ql<=mid)ret=(ret+query(lc,l,mid,ql,qr))%mod;
if(mid<qr)ret=(ret+query(rc,mid+1,r,ql,qr))%mod;
return ret;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++){
a[i]=read();
a[i]=(a[i]+a[i-1])%mod;
}
for(int i=1;i<=n;i++)a[i]=(a[i]+a[i-1])%mod;
build(1,1,n);
while(m--){
static int op,l,r,x,len;
op=read();l=read();r=read();
if(l>r)l^=r^=l^=r;
if(op==2){
cout<<((ll)(r-l+1)*query(1,1,n,n,n)-(r>1?query(1,1,n,max(1,l-1),r-1):0)-(l<n?query(1,1,n,max(1,n-r),n-l):0)+(mod<<1))%mod<<"\n";
}
else{
x=read();len=r-l+1;
modify(1,1,n,l,r,(ll)inv2*x%mod,((ll)(3-2*l)*inv2%mod*x%mod+mod)%mod,(((ll)l*l-3ll*l+2)%mod*inv2%mod*x%mod+mod)%mod);
if(r<n)modify(1,1,n,r+1,n,0,(ll)len*x%mod,((ll)(len+1)*inv2-r+mod)%mod*len%mod*x%mod);
}
}
return (0-0);
}
标签:BJOI2018,求和,sum,int,链上,lza,lzc,lzb,mod 来源: https://www.cnblogs.com/aurora2004/p/12579897.html