专栏文章

T683041 题解

个人记录参与者 1已保存评论 0

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@minjffyh
此快照首次捕获于
2025/12/02 03:24
3 个月前
此快照最后确认于
2025/12/02 03:24
3 个月前
查看原文
30pts:
纯送分。
直接暴力枚举 i,ji,j 并暴力计算 [i,j][i,j] 区间的和,时间复杂度 O(n3)O(n^3)
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=500009;
ll a[N],s[N],n,m,ans;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(ll i=1;i<=n;i++) cin>>a[i],s[i]=s[i-1]+a[i];
	for(ll i=1;i<=n;i++)
		for(ll j=i;j<=n;j++){
            ll s=0;
            for(ll k=i;k<=j;k++) s+=a[k];
            ans+=(s<=m);
        }
	cout<<ans<<endl;
	return 0;
}
但实际上这份代码可以获得 50pts,甚至能 n3n^3n=2543n=2543 的一个点。(966ms)
但有一组数据我造的比较大,大概 n=3700n=3700,于是我就没有放过 60pts。
60pts(测过,严格 60pts):
考虑用前缀和优化这一过程。直接把一段区间的和转化为 sisj1s_i-s_{j-1},时间复杂度 O(n2)O(n^2)
100pts:
考虑转化 sisj1ms_i-s_{j-1} \le m,变成 sisj1+ms_i \le s_{j-1}+m,然后枚举 jj,因为全部是正整数,二分 sis_i,求出 lower_bound 以后,就可以轻松解决了。
代码:
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=500009;
ll a[N],s[N],n,m,ans;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(ll i=1;i<=n;i++) cin>>a[i],s[i]=s[i-1]+a[i];
	for(ll i=1;i<=n;i++){
		ll j=lower_bound(s+1,s+1+n,s[i]+m)-(s+1);
		ans+=(j-i+1);
	}
	cout<<ans<<endl;
	return 0;
}
时间复杂度 O(nlogn)O(n \log n),跑的挺快,40ms 轻松过题。

评论

0 条评论,欢迎与作者交流。

正在加载评论...