首页 > 其他 > 详细

loj 6283 数列分块入门 7

时间:2019-08-06 00:57:10      阅读:135      评论:0      收藏:0      [点我收藏+]

技术分享图片

技术分享图片

技术分享图片

技术分享图片

技术分享图片

技术分享图片

 

题解:分块。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;
         }
      }
   }
}

 

loj 6283 数列分块入门 7

原文:https://www.cnblogs.com/VividBinGo/p/11306528.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!