分块求调

P3373 【模板】线段树 2

你可以看看我的代码(也是分块) ```cpp #include<bits/stdc++.h> #define ll long long #define m 571373 #define N 100009 using namespace std; ll n,q,_,L,a[N],b[N],bs[N],c[N],d[N]; void mul(ll x,ll y,ll k){ if(b[x]==b[y]) for(ll i=x;i<=y;i++)bs[b[i]]=(bs[b[i]]+a[i]*(k-1))%m,a[i]=(a[i]*k)%m; else{ for(ll i=b[x]+1;i<=b[y]-1;i++)c[i]=(c[i]*k)%m,d[i]=(d[i]*k)%m; // for(ll i=x;b[i]==b[x];i++)bs[b[i]]=(bs[b[i]]+a[i]*(k-1))%m,a[i]=(a[i]*k)%m; // for(ll i=y;b[i]==b[y];i--)bs[b[i]]=(bs[b[i]]+a[i]*(k-1))%m,a[i]=(a[i]*k)%m; bs[b[x]]=bs[b[y]]=0; for(ll i=(b[x]-1)*L+1;i<=min(n,b[x]*L);i++)a[i]=((a[i]*c[b[i]]+d[b[i]])*(i<x?1:k))%m,bs[b[i]]=(bs[b[i]]+a[i])%m;d[b[x]]=0,c[b[x]]=1; for(ll i=(b[y]-1)*L+1;i<=min(n,b[y]*L);i++)a[i]=((a[i]*c[b[i]]+d[b[i]])*(i>y?1:k))%m,bs[b[i]]=(bs[b[i]]+a[i])%m;d[b[y]]=0,c[b[y]]=1; } } void add(ll x,ll y,ll k){ if(b[x]==b[y]) for(ll i=x;i<=y;i++)bs[b[i]]=(bs[b[i]]+k)%m,a[i]=(a[i]+k)%m; else{ for(ll i=b[x]+1;i<=b[y]-1;i++)d[i]=(d[i]+k)%m; // for(ll i=x;b[i]==b[x];i++)bs[b[i]]=(bs[b[i]]+k)%m,a[i]=(a[i]+k)%m; // for(ll i=y;b[i]==b[y];i--)bs[b[i]]=(bs[b[i]]+k)%m,a[i]=(a[i]+k)%m; bs[b[x]]=bs[b[y]]=0; for(ll i=(b[x]-1)*L+1;i<=min(n,b[x]*L);i++)a[i]=(a[i]*c[b[i]]+(i<x?0:k)+d[b[i]])%m,bs[b[i]]=(bs[b[i]]+a[i])%m;d[b[x]]=0,c[b[x]]=1; for(ll i=(b[y]-1)*L+1;i<=min(n,b[y]*L);i++)a[i]=(a[i]*c[b[i]]+(i>y?0:k)+d[b[i]])%m,bs[b[i]]=(bs[b[i]]+a[i])%m;d[b[y]]=0,c[b[y]]=1; } } ll rsq(ll x,ll y){ ll s=0; if(b[x]==b[y]) for(ll i=x;i<=y;i++)s=(s+a[i]*c[b[i]]+d[b[i]])%m; else{ for(ll i=b[x]+1;i<=b[y]-1;i++)s=(s+(bs[i])*c[i]+d[i]*(min(n,L*b[i])-((b[i]-1)*L+1)+1))%m; for(ll i=x;b[i]==b[x];i++)s=(s+a[i]*c[b[i]]+d[b[i]])%m; for(ll i=y;b[i]==b[y];i--)s=(s+a[i]*c[b[i]]+d[b[i]])%m; } return s; } int main(){ cin>>n>>q>>_; L=sqrt(n); for(ll i=1;i<=n;i++)cin>>a[i]; for(ll i=1;i<=n;i++)b[i]=(i-1)/L+1; for(ll i=1;i<=n;i++)bs[b[i]]=(bs[b[i]]+a[i])%m; for(ll i=1;i<=n;i++)c[i]=1; #ifndef ONLINE_JUDGE for(ll i=1;i<=n;i++)cout<<i<<" a:"<<a[i]<<" b:"<<b[i]<<" bs:"<<bs[b[i]]<<"\n"; #endif for(ll i=1;i<=q;i++){ ll op,x,y,k; cin>>op; if(op==1){ cin>>x>>y>>k; mul(x,y,k); } else if(op==2){ cin>>x>>y>>k; add(x,y,k); } else{ cin>>x>>y; cout<<rsq(x,y)%m<<"\n"; } #ifndef ONLINE_JUDGE for(ll i=1;i<=n;i++)cout<<i<<" a:"<<a[i]<<" b:"<<b[i]<<" c:"<<c[b[i]]<<" d:"<<d[b[i]]<<" bs:"<<bs[b[i]]<<"\n"; #endif } return 0; } ```
by asas111 @ 2023-12-02 13:07:08


|