社区讨论
0pts求条玄关
P13978数列分块入门 3参与者 3已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mhj25d1e
- 此快照首次捕获于
- 2025/11/03 19:29 4 个月前
- 此快照最后确认于
- 2025/11/03 19:29 4 个月前
CPP
// Problem: P13978 数列分块入门 3
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P13978
// Memory Limit: 512 MB
// Time Limit: 6000 ms
#include<bits/stdc++.h>
namespace kimi{
#define int long long
#define pii pair<int, int>
#define fi first
#define se second
#define sept(x) fixed << setprecision(x)
#define pb emplace_back
#define endl '\n'
#define debug(x) cerr << x << endl
#define TLE AC
#define WA AC
using namespace std;
const int maxn = 3e5 + 10;
const int inf = 1e18;
int n, A[maxn];
int block, tot;
int L[maxn], R[maxn];
int pos[maxn];
int lazy[maxn];
vector<int> Sort[maxn];
void build(){
block = sqrt(n);
tot = (n + block - 1) / block;
for(int i = 1; i <= tot; i++){
L[i] = (i - 1) * block + 1;
R[i] = min(i * block, n);
for(int j = L[i]; j <= R[i]; j++) pos[j] = i, Sort[i].pb(A[j]);
sort(Sort[i].begin(), Sort[i].end());
}
memset(lazy, 0, sizeof lazy);
}
void change(int p, int l, int r, int v){
if(lazy[p]){
for(int i = L[p]; i <= R[p]; i++) A[i] += lazy[p];
lazy[p] = 0;
}
for(int i = l; i <= r; i++) A[i] += v;
Sort[p].clear();
for(int i = L[p]; i <= R[p]; i++) Sort[p].pb(A[i]);
sort(Sort[p].begin(), Sort[p].end());
}
void add(int l, int r, int v){
if(pos[l] == pos[r]){change(pos[l], l, r, v);return;}
change(pos[l], l, R[pos[l]], v);
change(pos[r], L[pos[r]], r, v);
for(int i = pos[l] + 1; i < pos[r]; i++) lazy[i] += v;
}
int ask(int p, int l, int r, int v){
int res = -inf;
for(int i = l; i <= r; i++){
if(A[i] + lazy[p] < v) res = max(res, A[i] + lazy[p]);
}
return res == -inf ? -1 : res;
}
int find(int p, int x){
int res = -1, l = 0, r = Sort[p].size() - 1;
while(l <= r){
int mid = l + r >> 1;
if(Sort[p][mid] < x) res = mid, l = mid + 1;
else r = mid - 1;
}
return res;
}
int query(int l, int r, int v){
int res = -inf;
if(pos[l] == pos[r]) return ask(pos[l], l, r, v);
res = max({res, ask(pos[l], l, R[pos[l]], v), ask(pos[r], L[pos[r]], r, v)});
for(int i = pos[l] + 1; i < pos[r]; i++){
int p = find(i, v - lazy[i]);
if(~p) res = max(res, Sort[i][p] + lazy[i]);
}
return res == -inf ? -1 : res;
}
void mian(){
cin >> n;
for(int i = 1; i <= n; i++) cin >> A[i];
build();
int op, l, r, x;
for(int i = 1; i <= n; i++){
cin >> op >> l >> r >> x;
if(!op) add(l, r, x);
else cout << query(l, r, x) << endl;
}
}
}using namespace kimi;
signed main(){
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0);
int Test = 1;
//cin >> Test;
while(Test--) mian();
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...