这题只要做对了前面的东东,这题肯定能做对的。(* ̄︶ ̄)
只要设m[i]表示第i块整体要乘的数,p[i]表示第i块整体要加的数即可。
记得!在乘c的时候要把p也给乘了(自己想想为什么)
还有,在做左右两边凸出来的东西的话,要先把整块的m[bl[i]],p[bl[i]]都附上去,然后清空(m[bl[i]]=1,p[bl[i]]=0),否则会有意想不到的错误!!!
上标:
#include<cstdio>
#include<algorithm>
#include<cmath>
#define mo 10007
#define N 100010
using namespace std;
int n,st,a[N],bl[N],le[N],ri[N];
int m[321],p[321],opt,l,r,c;
inline int read()
{
int x=0,f=0; char c=getchar();
while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return f ? -x:x;
}
void update(int x)
{
for (int i=le[x];i<=ri[x];i++)
a[i]=(m[x]*a[i]+p[x])%mo;
m[x]=1,p[x]=0;
}
void add(int l,int r,int c)
{
update(bl[l]);
for (int i=l;i<=min(ri[bl[l]],r);i++) a[i]+=c;
if (bl[l]!=bl[r])
{
update(bl[r]);
for (int i=le[bl[r]];i<=r;i++) a[i]+=c;
}
for (int i=bl[l]+1;i<=bl[r]-1;i++) p[i]+=c;
}
void cheng(int l,int r,int c)
{
update(bl[l]);
for (int i=l;i<=min(ri[bl[l]],r);i++) a[i]=a[i]*c%mo;
if (bl[l]!=bl[r])
{
update(bl[r]);
for (int i=le[bl[r]];i<=r;i++) a[i]=a[i]*c%mo;
}
for (int i=bl[l]+1;i<=bl[r]-1;i++)
m[i]=m[i]*c%mo,p[i]=p[i]*c%mo;
}
int main()
{
freopen("6283.in","r",stdin);
freopen("6283.out","w",stdout);
n=read();st=sqrt(n);
for (int i=1;i<=n;i++) a[i]=read();
for (int i=1;i<=n;i++)
{
bl[i]=(i-1)/st+1;
if (!le[bl[i]]) le[bl[i]]=i;
ri[bl[i]]=i;
}
for (int i=1;i<=bl[n];i++) m[i]=1;
for (int i=1;i<=n;i++)
{
opt=read(),l=read(),r=read(),c=read();
if (opt==0) add(l,r,c);
else if (opt==1) cheng(l,r,c);
else printf("%d
",(a[r]*m[bl[r]]+p[bl[r]])%mo);
}
return 0;
}