版权声明:欢迎转载(请附带原链接)ヾ(๑╹◡╹)ノ" https://blog.csdn.net/corsica6/article/details/84547285
传送门:bzoj5291
题解
设 为 的前缀和, 为 的前缀和。
每次询问所求
可化简为:
这是一个关于 的二元一次函数,可以化成 的形式用线段树维护标记下传。
代码
#include<bits/stdc++.h>
#define mid ((l+r)>>1)
#define lc k<<1
#define rc k<<1|1
using namespace std;
const int N=2e5+10,mod=1e9+7;
const int iv2=5e8+4;
typedef long long ll;
int n,m,a[N],pa[N],pb[N];
char cp,OS[100];
inline void rd(int &x)
{
cp=getchar();x=0;
for(;!isdigit(cp);cp=getchar());
for(;isdigit(cp);cp=getchar()) x=(x<<3)+(x<<1)+(cp^48);
}
inline void ot(int x)
{
int re=0;OS[0]='\n';
for(;(!re)||(x);x/=10) OS[++re]='0'+x%10;
for(;~re;--re) putchar(OS[re]);
}
inline int ad(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dc(int x,int y){x-=y;return x<0?x+mod:x;}
struct node{
int s,a,b,c;
inline void chg(node x,int l,int r)
{
if(x.a) a=ad(a,x.a),s=ad(s,(ll)x.a*dc(pa[r],pa[l-1])%mod);
if(x.b) b=ad(b,x.b),s=ad(s,(ll)x.b*dc(pb[r],pb[l-1])%mod);
if(x.c) c=ad(c,x.c),s=ad(s,(ll)x.c*(r-l+1)%mod);
}
inline void mul(int z){a=(ll)a*z%mod;b=(ll)b*z%mod;c=(ll)c*z%mod;}
}t[N<<2],tp;
void build(int k,int l,int r)
{
if(l==r) {t[k].s=a[l];return;}
build(lc,l,mid);build(rc,mid+1,r);
t[k].s=ad(t[lc].s,t[rc].s);
}
inline void pushdown(int k,int l,int r)
{
if((!t[k].a)&&(!t[k].b)&&(!t[k].c)) return;
t[lc].chg(t[k],l,mid);t[rc].chg(t[k],mid+1,r);
t[k].a=t[k].b=t[k].c=0;
}
void ad(int k,int l,int r,int L,int R)
{
if(L<=l && r<=R){t[k].chg(tp,l,r);return;}
pushdown(k,l,r);
if(L<=mid) ad(lc,l,mid,L,R);
if(R>mid) ad(rc,mid+1,r,L,R);
t[k].s=ad(t[lc].s,t[rc].s);
}
int ask(int k,int l,int r,int L,int R)
{
if(L<=l && r<=R) return t[k].s;
pushdown(k,l,r);
if(R<=mid) return ask(lc,l,mid,L,R);
if(L>mid) return ask(rc,mid+1,r,L,R);
return ad(ask(lc,l,mid,L,R),ask(rc,mid+1,r,L,R));
}
int main(){
int i,op,x,y,z,re;
rd(n);rd(m);
for(i=1;i<=n;++i) {rd(a[i]);a[i]=ad(a[i],a[i-1]);}
for(i=2;i<=n;++i) a[i]=ad(a[i],a[i-1]);
for(i=1;i<=n;++i) {pb[i]=ad(pb[i-1],i);pa[i]=ad(pa[i-1],(ll)i*i%mod);}
build(1,1,n);
for(;m;--m){
rd(op);rd(x);rd(y);if(x>y) swap(x,y);
if(op==1){
tp=(node){0,iv2,(ll)dc(3,ad(x,x))*iv2%mod,(ll)dc(ad((ll)x*x%mod,2),(ll)3*x%mod)*iv2%mod};
rd(z);tp.mul(z);ad(1,1,n,x,y);
if(y<n){
x=y-x+1;tp=(node){0,0,x,dc(pb[x],(ll)y*x%mod)};tp.mul(z);
ad(1,1,n,y+1,n);
}
}else{
re=(ll)(y-x+1)*ask(1,1,n,n,n)%mod;z=0;
if(y>1) z=ask(1,1,n,max(1,x-1),y-1);
if(n>x) z=ad(z,ask(1,1,n,max(1,n-y),n-x));
ot(dc(re,z));
}
}
return 0;
}