社区讨论

TLE如何治疗

P13978数列分块入门 3参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@mlknsv4p
此快照首次捕获于
2026/02/13 17:02
6 天前
此快照最后确认于
2026/02/16 17:50
3 天前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
#define ll long long
// #define ll unsigned long long
const ll N = 2e5 + 10;
ll n,a[N],lump_plus[N],S,in[N];
multiset<ll>have[N];
inline void add(ll l,ll r,ll c){
	for (ll i = l;i <= min(in[l] * S,r);i++){
		have[in[i]].erase(have[in[i]].find(a[i]));
		a[i] += c;
		have[in[i]].insert(a[i]);
	}
	if (in[l] == in[r]) return;
	for (ll i = in[l] + 1;i < in[r];i++){
		lump_plus[i] += c;
	}
	for (ll i = (in[r] - 1) * S + 1;i <= r;i++){
		have[in[i]].erase(have[in[i]].find(a[i]));
		a[i] += c;
		have[in[i]].insert(a[i]);
	}
}
ll query(ll l,ll r,ll x){
	ll tot = LONG_LONG_MIN,val;
	for (ll i = l;i <= min(in[l] * S,r);i++){
		val = a[i] + lump_plus[in[i]];
		if (val < x){
			tot = max(tot,val);
		}
	}
	if (in[l] == in[r]) return (tot == LONG_LONG_MIN ? -1 : tot);
	for (ll i = (in[r] - 1) * S + 1;i <= r;i++){
		val = a[i] + lump_plus[in[i]];
		if (val < x){
			tot = max(tot,val);
		}
	}
	for (ll i = in[l] + 1;i < in[r];i++){
		auto it = have[i].lower_bound(x - lump_plus[i]);
		if (it != have[i].begin()){
			--it;
			tot = max(tot,*it + lump_plus[i]);
		}
	}
	return (tot == LONG_LONG_MIN ? -1 : tot);
}
void run(){
	ll op,l,r,c;
	cin>>n;
	S = sqrt(n);
	for (ll i = 1;i <= n;i++){
		cin>>a[i];
		in[i] = (i - 1) / S + 1;
		have[in[i]].insert(a[i]);
	}
	for (ll t = 1;t <= n;t++){
		cin>>op>>l>>r>>c;
		if (op == 0){
			add(l,r,c);
		}
		else{
			cout<<query(l,r,c)<<endl;
		}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	// freopen("seq.in","r",stdin);
	// freopen("seq.out","w",stdout);
	run();
	return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...