- 数列分块入门 3
-TJ
- 2024-2-1 13:28:12 @
/* created by chjshen, date: 2024-02-01 12:59 */
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
#define int long long
const int N = 1E5 + 5;
const int INF = 1e18;
int n, a[N];
int L[N], R[N], pos[N], add[N], b[N];
int bl, bn;
void update(int l, int r, int c)
{
int lb = pos[l], rb = pos[r];
if (lb == rb)
{
for (int i = l; i <= r; i++) a[i] += c;
for (int i = L[lb]; i <= R[lb]; i++) b[i] = a[i];
sort(b + L[lb], b + R[lb] + 1);
}
else
{
// 1. 前面的
for (int i = l; i <= R[lb]; i++) a[i] += c;
for (int i = L[lb]; i <= R[lb]; i++) b[i] = a[i];
sort(b + L[lb], b + R[lb] + 1);
// 2. 中间完全覆盖的块
for (int i = lb + 1; i <= rb - 1; i++) add[i] += c;
// 3. 后面的
for (int i = L[rb]; i <= r; i++) a[i] += c;
for (int i = L[rb]; i <= R[rb]; i++) b[i] = a[i];
sort(b + L[rb], b + R[rb] + 1);
}
}
int search(int l, int r, int c)
{
int res = -INF;
while (l <= r)
{
int mid = (l + r) >> 1;
if (b[mid] + add[pos[mid]] < c)
{
res = mid;
l = mid + 1;
}
else
r = mid - 1;
}
return res == -INF ? res : b[res] + add[pos[l]];
}
void query(int l, int r, int c)
{
int lb = pos[l], rb = pos[r];
int ans = -INF;
if (lb == rb)
{
for (int i = l; i <= r; i++)
if (a[i] + add[lb] < c) ans = max(ans, a[i]);
}
else
{
// 1. pre
for (int i = l; i <= R[lb]; i++)
if (a[i] + add[lb] < c) ans = max(ans, a[i] + add[lb]);
// 2. mid
for (int i = lb + 1; i <= rb - 1; i++)
{
ans = max(ans, search(L[i], R[i], c));
}
// 3. after
for (int i = L[rb]; i <= r; i++)
if (a[i] + add[rb] < c) ans = max(ans, a[i] + add[rb]);
}
if (ans == -INF) ans = -1;
cout << ans << endl;
}
void handle(void)
{
int opt, l, r, c;
cin >> opt >> l >> r >> c;
if (opt == 0)
update(l, r, c);
else
query(l, r, c);
}
void initInput(void)
{
ios::sync_with_stdio(0);
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i];
}
// init block
bl = sqrt(n);
bn = n / bl;
for (int i = 1; i <= bn; i++)
{
L[i] = (i - 1) * bl + 1;
R[i] = i * bl;
for (int j = L[i]; j <= R[i]; j++)
{
pos[j] = i;
}
sort(b + L[i], b + R[i] + 1);
}
if (n > bl * bn)
{
bn++;
L[bn] = (bn - 1) * bl + 1;
R[bn] = n;
for (int j = L[bn]; j <= n; j++)
{
pos[j] = bn;
}
sort(b + L[bn], b + n + 1);
}
}
signed main(void)
{
initInput();
handle();
return 0;
}
8 条评论
-
王艺豪 LV 10 MOD @ 2024-2-1 13:35:14
qp -
2024-2-1 13:31:25@
-
2024-2-1 13:30:35@
qp
-
2024-2-1 13:30:28@
hp
-
2024-2-1 13:30:22@
qp
-
2024-2-1 13:30:08@
qp for(int i=1;i<=n;i++)handle();
-
2024-2-1 13:29:37@
qp
-
2024-2-1 13:28:55@
qp
- 1
信息
- ID
- 2598
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 259
- 已通过
- 24
- 上传者