A Simple Problem with Integers POJ

题目链接:https://cn.vjudge.net/problem/POJ-3468

题目大意:区间加减+区间查询操作。

具体思路:本来是一个线段树裸题,为了学习分块就按照分块的方法做吧。

分块真的好暴力,,,(但是还是挺优美的)。

说一下各个数组的作用。

a数组,代表每一个点的值。

sum数组,代表分块后每一段的值。

add数组,相当于线段树中的lazy标记,记录的数当前这一整段添加的值。

l数组,r数组,记录每一段的左端点和右端点。

belong数组,记录每一个数属于哪一个分块中。

AC代码:

 1 #include<iostream>
 2 #include<stack>
 3 #include<string>
 4 #include<stdio.h>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<math.h>
 8 using namespace std;
 9 # define ll long long
10 const int maxn = 1e6+100;
11 ll a[maxn],sum[maxn],add[maxn];
12 int l[maxn],r[maxn];
13 int belong[maxn];
14 void buildblock(int t){
15 int tmp=(int)sqrt(t*1.0);
16 int tot=t/tmp;
17 if(t%tmp)tot++;
18 for(int i=1;i<=t;i++){
19 belong[i]=(i-1)/tmp+1;
20 }
21 for(int i=1;i<=tot;i++){
22 l[i]=(i-1)*tmp+1;
23 r[i]=i*tmp;
24 }
25 r[tot]=t;
26 for(int i=1;i<=tot;i++){
27 for(int j=l[i];j<=r[i];j++){
28 sum[i]+=a[j];
29 }
30 }
31 }
32 void update(int st,int ed,ll val){
33 if(belong[st]==belong[ed]){
34 for(int i=st;i<=ed;i++){
35 a[i]+=val;
36 sum[belong[st]]+=val;
37 }
38 return ;
39 }
40 for(int i=st;i<=r[belong[st]];i++){
41 a[i]+=val;
42 sum[belong[st]]+=val;
43 }
44 for(int i=l[belong[ed]];i<=ed;i++){
45 a[i]+=val;
46 sum[belong[ed]]+=val;
47 }
48 for(int i=belong[st]+1;i<belong[ed];i++){
49 add[i]+=val;
50 }
51 }
52 ll ask(int st,int ed){
53 ll ans=0;
54 if(belong[st]==belong[ed]){
55 for(int i=st;i<=ed;i++){
56 ans+=a[i]+add[belong[st]];
57 }
58 return ans;
59 }
60 for(int i=st;i<=r[belong[st]];i++){
61 ans+=a[i]+add[belong[st]];
62 }
63 for(int i=l[belong[ed]];i<=ed;i++){
64 ans+=a[i]+add[belong[ed]];
65 }
66 for(int i=belong[st]+1;i<belong[ed];i++){
67 ans+=sum[i]+add[i]*(r[i]-l[i]+1);
68 }
69 return ans;
70 }
71 int main(){
72 //freopen("hqx.in","r",stdin);
73 int n,m;
74 scanf("%d %d",&n,&m);
75 for(int i=1;i<=n;i++){
76 scanf("%lld",&a[i]);
77 }
78 buildblock(n);
79 char str[10];
80 int st,ed;
81 ll cost;
82 while(m--){
83 scanf("%s",str);
84 if(str[0]=='Q'){
85 scanf("%d %d",&st,&ed);
86 printf("%lld
",ask(st,ed));
87 }
88 else if(str[0]=='C'){
89 scanf("%d %d %lld",&st,&ed,&cost);
90 update(st,ed,cost);
91 }
92 }
93 return 0;
94 }