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 }