loj 6283 数列分块入门 7
题解:分块。sum[i]维护 i 块增加的数,m[i]维护 i 块扩大的倍数。及时更新。=w[r] * m[r] + sum[r]。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005,mod=10007;
int n,block;
long long w[maxn],sum[maxn],m[maxn];
int get(int x);
void reset(int k);
void update(int op,int l,int r,int c);
int main()
{
fill(sum,sum+maxn,0);
fill(m,m+maxn,1);
int i,op,l,r,c;
scanf("%d",&n);
block=sqrt(n);
for(i=1;i<=n;i++)
{
scanf("%lld",&w[i]);
w[i]%=mod;
}
for(i=0;i<n;i++)
{
scanf("%d%d%d%d",&op,&l,&r,&c);
if(op==2) printf("%lld\n",(w[r]*m[get(r)]+sum[get(r)])%mod);
else update(op,l,r,c);
}
system("pause");
return 0;
}
int get(int x)
{return (x-1)/block+1;}
void reset(int k)
{
for(int i=(k-1)*block+1;i<=min(k*block,n);i++)
w[i]=(w[i]*m[k]+sum[k])%mod;
m[k]=1;sum[k]=0;
}
void update(int op,int l,int r,int c)
{
int pre,end,k;
pre=get(l);end=get(r);
reset(pre);reset(end);
if(pre==end)
{
for(k=l;k<=r;k++)
{
if(op==0) w[k]=(w[k]+c)%mod;
else w[k]=(w[k]*c)%mod;
}
}
else
{
for(k=l;k<=min(pre*block,n);k++)
{
if(op==0) w[k]=(w[k]+c)%mod;
else w[k]=(w[k]*c)%mod;
}
for(k=(end-1)*block+1;k<=r;k++)
{
if(op==0) w[k]=(w[k]+c)%mod;
else w[k]=(w[k]*c)%mod;
}
for(k=pre+1;k<end;k++)
{
if(op==0) sum[k]=(sum[k]+c)%mod;
else
{
sum[k]=(sum[k]*c)%mod;
m[k]=(m[k]*c)%mod;
}
}
}
}