拿斐波那契数列来说吧,区间加上一段。
显然对于单点求值得时候我们可以自前向后遍历,类扫描线一样。
先阐述一下最 navie 的暴力。枚举每一个操作,自前向后,若遇到它的左端点,则代表接下来的都需要递推了,也就是 fl−1=0,fl=1,fl+1=fl+fl−1,如是递推下去,但是到 r 结束了,下一位是 r+1 的时候,这个操作的贡献就要消掉了,也就是对应减去最后所得到的斐波那契数。
考虑合并所有操作变成一次遍历,最想当然正确的办法是不是扩域?但显然我们发现并不需要管那么多,因为加法满足结合律,自然这样搞下去即可。
然后套个根号分治!
http://www.51nod.com/Contest/ProblemSubmitDetail.html#judgeId=232860
#include <bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int mod=19260817,N=(int)(1e5+5),M=350;
int id[N],L[M],R[M],n,m,D,bl,a[N],sf[N],sum[N],p[N],sp[N],f[N],sd[N];
namespace sol1 {
int tag1[M],tag2[M],tag3[M],s[N],ss[M];
void upt(int l,int r,int k,int d) {
if(id[l]==id[r]) {
for(int i=l;i<=r;i++) {
s[i]=(s[i]+k+(i-l)*d%mod)%mod;
ss[id[i]]=(ss[id[i]]+k+(i-l)*d%mod)%mod;
}
} else {
for(int i=l;i<=R[id[l]];i++) s[i]=(s[i]+k+(i-l)*d%mod)%mod,ss[id[i]]=(ss[id[i]]+k+(i-l)*d%mod)%mod;
for(int i=L[id[r]];i<=r;i++) s[i]=(s[i]+k+(i-l)*d%mod)%mod,ss[id[i]]=(ss[id[i]]+k+(i-l)*d%mod)%mod;
for(int i=id[l]+1;i<id[r];i++) {
tag1[i]=(tag1[i]+k)%mod;
tag2[i]=(tag2[i]+(L[i]-l)*d%mod)%mod;
tag3[i]=(tag3[i]+d)%mod;
}
}
}
int qry(int l,int r) {
if(id[l]==id[r]) {
int res=0;
for(int i=l;i<=r;i++) res=((res+s[i])%mod+tag1[id[i]]+tag2[id[i]]+(i-L[id[i]])*tag3[id[i]]%mod)%mod;
return res;
} else {
int res=0;
for(int i=l;i<=R[id[l]];i++) res=((res+s[i])%mod+tag1[id[i]]+tag2[id[i]]+(i-L[id[i]])*tag3[id[i]]%mod)%mod;
for(int i=L[id[r]];i<=r;i++) res=((res+s[i])%mod+tag1[id[i]]+tag2[id[i]]+(i-L[id[i]])*tag3[id[i]]%mod)%mod;
for(int i=id[l]+1;i<id[r];i++) {
int qwq=R[i]-L[i]+1;
res=(res+qwq*tag1[i]%mod+tag2[i]*qwq%mod+sd[qwq-1]*tag3[i]%mod+ss[i])%mod;
}
return res;
}
}
}
namespace sol2 {
int tag[M],s[N],ss[M];
void upt(int l,int r,int k) {
if(id[l]==id[r]) {
for(int i=l;i<=r;i++) {
s[i]=(s[i]+k*p[i-l]%mod)%mod;
ss[id[i]]=(ss[id[i]]+k*p[i-l]%mod)%mod;
}
} else {
for(int i=l;i<=R[id[l]];i++) s[i]=(s[i]+k*p[i-l]%mod)%mod,ss[id[i]]=(ss[id[i]]+k*p[i-l]%mod)%mod;
for(int i=L[id[r]];i<=r;i++) s[i]=(s[i]+k*p[i-l]%mod)%mod,ss[id[i]]=(ss[id[i]]+k*p[i-l]%mod)%mod;
for(int i=id[l]+1;i<id[r];i++) {
tag[i]=(tag[i]+k*p[L[i]-l]%mod)%mod;
}
}
}
int qry(int l,int r) {
if(id[l]==id[r]) {
int res=0;
for(int i=l;i<=r;i++) res=((res+s[i])%mod+tag[id[i]]*p[i-L[id[i]]]%mod)%mod;
return res;
} else {
int res=0;
for(int i=l;i<=R[id[l]];i++) res=(res+s[i]+tag[id[i]]*p[i-L[id[i]]])%mod;
for(int i=L[id[r]];i<=r;i++) res=(res+s[i]+tag[id[i]]*p[i-L[id[i]]])%mod;
for(int i=id[l]+1;i<id[r];i++) res=(res+ss[i]+tag[i]*sp[R[i]-L[i]]%mod)%mod;
return res;
}
}
}
int lim;
namespace sol3 {
vector<int>vecl[N],vecr[N];
int tot,l[N],r[N],v[N],val[N];
inline void re() {
for(int i=1;i<=tot;i++) {
vecl[l[i]].pb(i); vecr[r[i]].pb(i);
}
int a=0,b=0;
for(int i=1;i<=n;i++) {
int c=(a+b)%mod;
val[i]=(val[i]+c)%mod;
a=b; b=c;
for(auto x:vecl[i]) b=(b+1)%mod,val[i]=(val[i]+1)%mod;
for(auto x:vecr[i]) {
int L=l[x],R=r[x];
b=(b-f[R-L+1]); a=(a-f[R-L]);
}
v[i]=(v[i-1]+val[i])%mod;
}
for(int i=1;i<=tot;i++) vecl[l[i]].clear(),vecr[r[i]].clear();
tot=0;
}
inline void upt(int x,int y) {
l[++tot]=x; r[tot]=y;
if(tot==lim) re();
}
inline int qry(int x,int y) {
int res=v[y]-v[x-1];
for(int i=1;i<=tot;i++) {
int L=max(x,l[i]),R=min(y,r[i]);
if(L<=R) {
res=(res+sf[R-l[i]+1]-sf[L-l[i]])%mod;
}
}
return res;
}
}
signed main() {
cin.tie(0); ios::sync_with_stdio(false);
cin>>n>>m>>D; bl=sqrt(n); lim=sqrt(m);
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) a[i]=(a[i]+a[i-1])%mod;
for(int i=1;i<=n;i++) id[i]=(i-1)/bl+1;
for(int i=1;i<=id[n];i++) L[i]=(i-1)*bl+1,R[i]=i*bl; R[id[n]]=n;
p[0]=1;
for(int i=1;i<=n;i++) p[i]=p[i-1]*D%mod;
sp[0]=1;
for(int i=1;i<=n;i++) sp[i]=(p[i]+sp[i-1])%mod;
f[1]=1; f[2]=1; for(int i=3;i<=n;i++) f[i]=(f[i-1]+f[i-2])%mod;
for(int i=1;i<=n;i++) sf[i]=(sf[i-1]+f[i])%mod;
sd[0]=0; for(int i=1;i<=n;i++) sd[i]=(sd[i-1]+i)%mod;
while(m--) {
int op; cin>>op;
if(op==1) {
int l,r,x,y;
cin>>l>>r>>x>>y;
sol1::upt(l,r,x,y);
} else if(op==2) {
int l,r,x; cin>>l>>r>>x;
sol2::upt(l,r,x);
} else if(op==3) {
int l,r; cin>>l>>r;
sol3::upt(l,r);
} else {
int l,r; cin>>l>>r;
int res=(sol2::qry(l,r)+sol1::qry(l,r)+sol3::qry(l,r))%mod;
res=(res+a[r]-a[l-1])%mod;
cout<<(res%mod+mod)%mod<<'\n';
}
}
return 0;
}
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】