社区讨论

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 条回复,欢迎继续交流。

正在加载回复...