#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e4 + 10;
int T, n, block, num, L[MAXN], R[MAXN], belong[MAXN], sum[MAXN], a[MAXN];
void build ()
{
memset (sum, 0, sizeof (sum));
block = sqrt(n);
num = n/block; //块的数目
if (n%block) num++;//+1;
for (int i = 1; i <= num; i++) //每个块的 左右
{
L[i] = (i - 1)*block + 1;
R[i] = i*block;
}
R[num] = n;
for (int i = 1; i <= n; i++)//每个点属于哪个块;
{
belong[i] = (i - 1)/block + 1;
}
for (int i = 1; i <= num; i++)//num 个块
{
for (int j = L[i]; j <= R[i]; j++)//每个块的值
{
sum[i] += a[j];
}
}
}
void update (int x, int y)
{
a[x] += y;
sum[belong[x]] += y;//属于x的块的和加y;
}
int ask (int x, int y)//x到y的总和
{
int res = 0;
if (belong[x] == belong[y])// x与y同一块
{
for (int i = x; i <= y; i++)
res += a[i];
return res;
}
for (int i = x; i <= R[belong[x]]; i++)
{
res += a[i];
}
for (int i = belong[x] + 1; i < belong[y]; i++)
{
res += sum[i];
}
for (int i = L[belong[y]]; i <= y; i++)
{
res += a[i];
}
return res;
}
nt main ()
{
scanf ("%d", &T);
for (int kase = 1; kase <= T; kase ++)
{
scanf ("%d", &n);
for (int i = 1; i <= n; i++)
scanf ("%d", &a[i]);
build();
char op[10];
printf("Case %d:\n", kase);
while (scanf ("%s", op) != EOF && op[0] != 'E')
{
int x, y;
scanf ("%d%d", &x, &y);
if (op[0] == 'Q')
{
printf("%d\n", ask(x, y));
} else if (op[0] == 'A')
{
update (x, y);
} else if (op[0] == 'S')
{
update (x, -y);
}
}
}
return 0;
}
分块模板【大段维护 局部朴素】
最新推荐文章于 2022-12-02 10:57:05 发布