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
",(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;
         }
      }
   }
}
本博客仅为本人学习,总结,归纳,交流所用,若文章中存在错误或有不当之处,十分抱歉,劳烦指出,不胜感激!!!
原文地址:https://www.cnblogs.com/VividBinGo/p/11306528.html