优化暴力算法
分sqrt(n)个区间进行维护
复杂度3 sqrt(n) = sqrt(n)
代码: 建块
int n, m;
ll arr[MAXN] = {0}; //原数组
ll belong[MAXN], bsize = 0; //对应块 块大小
ll fst[MAXN], lst[MAXN], rmax[MAXN] = {0}; //对应块起始地址 块维护信息
void build()
{
bsize = sqrt(n);
for(int i = 1; i <= bsize; ++i)
fst[i] = (i - 1) * bsize + 1, lst[i] = i * bsize;
if(lst[bsize] < n)
++bsize, fst[bsize] = lst[bsize - 1] + 1, lst[bsize] = n; //维护尾段
for(int i = 1; i <= bsize; ++i)
for(int j = fst[i]; j <= lst[i]; ++j)
belong[j] = i;
}
查询:
ll ask(int x, int y)
{
ll ans = 0;
if(belong[x] == belong[y]) //同一块内暴力查询
{
for(int i = x; i <= y; ++i)
ans = max(ans, arr[i]);
}
else
{
for(int i = x; i <= lst[ belong[x]]; ++i ) //暴力查询区间
ans = max(ans, arr[i]);
for(int i = belong[x] + 1; i < belong[y]; ++i) //快速查询块内信息
ans = max(ans, rmax[i]);
for(int i = fst[belong[y]]; i <= y; ++i) //暴力查询后区间
ans = max(ans, arr[i]);
}
return ans;
}
区间加和区间和模板
/*
Zeolim - An AC a day keeps the bug away
*/
//pragma GCC optimize(2)
#include <bits/stdc++.h>
#include<queue>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, y, z) for(int x = y; x < z; ++x)
typedef long long ll;
typedef double ld;
typedef std::pair<int, int> pii;
typedef std::vector <short> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 1e18;
const ll MOD = 1e9 + 7;
const int MAXN = 1e6 + 100;
int n, m;
ll arr[MAXN] = {0}; //原数组
ll belong[MAXN], bsize = 0; //对应块 块大小
ll fst[MAXN], lst[MAXN], sum[MAXN] = {0}, add[MAXN] = {0}; //对应块起始地址 块维护信息
void build()
{
bsize = sqrt(n);
for(int i = 1; i <= bsize; ++i)
fst[i] = (i - 1) * bsize + 1, lst[i] = i * bsize;
if(lst[bsize] < n)
++bsize, fst[bsize] = lst[bsize - 1] + 1, lst[bsize] = n; //维护尾段
for(int i = 1; i <= bsize; ++i)
for(int j = fst[i]; j <= lst[i]; ++j)
{
belong[j] = i;
sum[i] += arr[j];
}
}
ll ask(int x, int y)
{
ll ans = 0;
if(belong[x] == belong[y]) //同一块内暴力查询
{
for(int i = x; i <= y; ++i)
ans = ans + arr[i] + add[belong[x]];
}
else
{
for(int i = x; i <= lst[ belong[x]]; ++i ) //暴力查询区间
ans = ans + arr[i] + add[belong[i]];
for(int i = belong[x] + 1; i < belong[y]; ++i) //快速查询块内信息
ans += sum[i];
for(int i = fst[belong[y]]; i <= y; ++i) //暴力查询后区间
ans = ans + arr[i] + add[belong[i]];
}
return ans;
}
void change(int x, int y, int val)
{
if(belong[x] == belong[y]) //同一块内暴力查询
{
for(int i = x; i <= y; ++i)
arr[i] += val, sum[belong[i]] += val;
}
else
{
for(int i = x; i <= lst[ belong[x]]; ++i ) //暴力查询区间
arr[i] += val, sum[belong[i]] += val;
for(int i = belong[x] + 1; i < belong[y]; ++i) //快速查询块内信息
add[i] += val, sum[i] += (lst[i] - fst[i] + 1) * val;
for(int i = fst[belong[y]]; i <= y; ++i) //暴力查询后区间
arr[i] += val, sum[belong[i]] += val;
}
}
int main()
{
//ios::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
//freopen("d:\out.txt","w",stdout);
//freopen("d:\in.txt","r",stdin);
scanf("%d%d", &n, &m);
fr(i, 1, n + 1)
scanf("%lld", &arr[i]);
build();
char op;
int x, y, z;
fr(i, 0, m)
{
scanf(" %c", &op);
if(op == 'Q')
{
scanf("%d%d", &x, &y);
printf("%lld\n", ask(x, y));
}
else
{
scanf("%d%d%d", &x, &y, &z);
change(x, y, z);
}
}
return 0;
}