\(\text{LibreOJ}\) 数列分块入门 \(1 \sim 9\)
区间加, 单点查询:
直接暴力分块
完整块 修改永久懒标记
两端不完整块暴力修改元素值
单点查询值 = 元素值 + 懒标记完整块数量不超过 \(\sqrt n\), 两不完整块总长度不超过 \(2 \sqrt n\)
总复杂度\(O(n \sqrt{n})\)
//知识点:分块
/*
By:Luckylazy
题目要求:
区间加, 单点查询
算法实现:
直接暴力分块
完整块 修改永久懒标记
两端不完整块暴力修改元素值
单点查询值 = 元素值 + 懒标记
完整块数量不超过 $\sqrt n$, 两不完整块总长度不超过 $2 \sqrt n$
总复杂度$O(n \sqrt{n})$
*/
#include <cstdio>
#include <cctype>
#include <cmath>
#define ll long long
const int MARX = 5e4 + 10;
//===========================================================
//Belong:元素所在块的编号; Fir, Las:第i个块的左右边界
int N, lazyNum, Belong[MARX], Fir[MARX], Las[MARX];
ll Number[MARX], lazy[MARX]; //Number:元素值; lazy:第i个块的永久懒标记
//===========================================================
inline int read()
{
int w = 0, f = 1; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');
return f * w;
}
void Prepare() //预处理
{
N = read();
for(int i = 1; i <= N; i ++) Number[i] = (ll) read();
lazyNum = sqrt(N);
for(int i = 1; i <= lazyNum; i ++) //进行分块
Fir[i] = (i - 1) * lazyNum + 1,
Las[i] = i * lazyNum;
//处理数列尾的 不完整块
if(Las[lazyNum] < N) lazyNum ++, Fir[lazyNum] = Las[lazyNum - 1] + 1, Las[lazyNum] = N;
for(int i = 1; i <= lazyNum; i ++) //处理每个元素 所在块的编号
for(int j = Fir[i]; j <= Las[i]; j ++)
Belong[j] = i;
}
void Change(int L, int R, ll Val) //区间加
{
if(Belong[L] == Belong[R]) //当修改区间 被一个块包含 (不完整块
{
for(int i = L; i <= R; i ++) Number[i] += Val; //直接暴力修改
return ;
}
for(int i = Belong[L] + 1; i <= Belong[R] - 1; i ++) lazy[i] += Val; //修改完整块
for(int i = L; i <= Las[Belong[L]]; i ++) Number[i] += Val; //修改左端不完整块
for(int i = Fir[Belong[R]]; i <= R; i ++) Number[i] += Val; //修改右端不完整块
}
//===========================================================
int main()
{
Prepare();
for(int i = 1; i <= N; i ++)
{
int opt = read(), L = read(), R = read(), Val = read();
if(! opt) Change(L, R, (ll) Val);
else printf("%lld\n", Number[R] + lazy[Belong[R]]); //单点查询
}
return 0;
}
- 区间加, 区间查询小于给定值 元素数:
- 区间加, 区间查询小于给定值 最大元素:
- 区间加, 区间求和:
- 区间开方, 区间求和:
- 单点插入,单点查询:
- 区间加, 区间乘, 区间求和:
- 区间赋值, 查询区间等于给定值 元素数:
gugunb
- 查询区间最小众数:
guguwansui