A Simple Problem with Integers POJ - 3468 分块

题意:

给你n个数,你只能对这n个数进行两种操作

1、C a b c :给区间[a,b]的每一个数都加上c

2、Q a b   :询问区间[a,b]中所有数的和

 

题解:

首先我们要找到对于分块后的每一块我们要维护什么东西。题意很清晰,我们要维护一个区间中所有数的和。对于区间更新以及查询还是看代码吧!

 

代码:

  1 #include <iostream>
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<algorithm>
  5 #include<math.h>
  6 using namespace std;
  7 const int maxn=100005;
  8 typedef long long ll;
  9 ll a[maxn],belong[maxn],b[maxn],sum[maxn],di_jia[maxn];
 10 ll n,m,v;
 11 ll block, num,l[maxn],r[maxn];
 12 long long  lazy[maxn];
 13 /*
 14 如果要对一个完整块要加上v,那么我们肯定不能遍历这一个块(因为这样就和暴力没有区别了)。所有我们要搞一个lazy数组
 15 来记录一下对于一个块要附加的值
 16 
 17 注意:只有对完整块才会对lazy数组对应块加上v,对于不完整块我们就要采用遍历的方式
 18 */
 19 void build()  //分块代码
 20 {
 21     block=sqrt(n);
 22     num=n/block;
 23     for(ll i=1; i<=num; ++i)
 24     {
 25         l[i]=block*(i-1)+1;
 26         r[i]=block*i;
 27     }
 28     r[num]=n;
 29 
 30     for(ll i=1; i<=num; ++i)
 31     {
 32         for(ll j=l[i]; j<=r[i]; ++j)
 33         {
 34             belong[j]=i;
 35         }
 36         sum[i]=b[r[i]]-b[l[i]-1];
 37     }
 38 }
 39 ll query(int x,int y)  //区间查询代码
 40 {
 41     ll ans=0;
 42     if(belong[x]==belong[y])
 43     {
 44 
 45         for(ll i=x; i<=y; ++i)
 46         {
 47             ans+=a[i]+lazy[belong[x]];  //最开始代码错就是这里没有加上懒惰标记
 48         }
 49     }
 50     else
 51     {
 52         for(ll i=x; i<=r[belong[x]]; i++)
 53         {
 54             ans=ans+a[i]+lazy[belong[x]];
 55         }
 56 
 57         for(ll i=belong[x]+1; i<belong[y]; i++)
 58         {
 59             ans+=sum[i] + lazy[i]*block;
 60         }
 61 
 62         for(ll i=l[belong[y]]; i<=y; i++)
 63         {
 64             ans=ans+a[i]+lazy[belong[y]];
 65         }
 66     }
 67     return ans;
 68 }
 69 void update(int x,int y,int z)  //区间更新代码
 70 {
 71     if(belong[x]==belong[y])
 72     {
 73         for(ll i=x; i<=y; ++i)
 74         {
 75             a[i]+=z;
 76         }
 77         sum[belong[x]]+=(y-x+1)*z;
 78     }
 79     else
 80     {
 81         for(ll i=x; i<=r[belong[x]]; i++)
 82         {
 83             a[i]+=z;
 84         }
 85         sum[belong[x]]+=(r[belong[x]]-x+1)*z;
 86 
 87         for(ll i=belong[x]+1; i<belong[y]; i++)
 88         {
 89             lazy[i]+=z;
 90         }
 91 
 92         for(ll i=l[belong[y]]; i<=y; i++)
 93         {
 94             a[i]+=z;
 95         }
 96         sum[belong[y]]+=(y-l[belong[y]]+1)*z;
 97     }
 98 }
 99 int main()
100 {
101 
102     while(~scanf("%lld%lld",&n,&m))
103     {
104         ll x,y,z;
105         memset(di_jia,0,sizeof(di_jia));
106         memset(b,0,sizeof(b));
107         memset(lazy,0,sizeof(lazy));
108         for(ll i=1; i<=n; ++i)
109             scanf("%lld",&a[i]),b[i]=a[i]+b[i-1];
110         build();
111         char ch[5];
112         while(m--)
113         {
114             scanf("%s",ch);
115             if(ch[0]=='Q')
116             {
117                 scanf("%lld%lld",&x,&y);
118                 printf("%lld\n",query(x,y));
119             }
120             else
121             {
122                 scanf("%lld%lld%lld",&x,&y,&z);
123                 update(x,y,z);
124             }
125         }
126     }
127     return 0;
128 }

 

 

 

 

上一篇:SwiftUI 内功之 如何改造所有视图为lazy (教程含源码)


下一篇:react 懒加载和错误边界