#P1497. 2023.08.26-MT-第五题-塔子哥的平均数(前缀和)

https://codefun2000.com/p/P1497

题目内容

给定一个正整数数组\(a_1,a_2,...,a_n\),求平均数正好等于k的最长连续子数组的长度

输入描述

第一行输入两个正整数\(n\)\(k\)

第二行输入n个正整数\(a_i\)

,用来表示数组

\(1 \leq n \leq 1e5\)

\(1≤ k,a_i \leq 1e9\)

输出描述

输出一个整数,表示最长满足题目条件的长度。

样例

输入

5 2
1 3 2 4 1

输出

3

给定一个数组,要求找到一个连续子数组的平均值为kk,并且其长度是符合条件子数组里最长的,求其长度。
可以考虑前缀和的做法来解此题。要求连续子数组平均值为\(k\),让每个数\(a_i^{、}=a_i-k\),那么如果一段连续子数组平均值和为\(k\),则这一段数组的和为\(0\)\(\sum{a_i^{、}=\sum{a_i}-k*length}=0\).
扩展开来,如果前缀和中出现某两个位置的值相等,那么根据前缀和的定义,他们间的这一段的和为\(0\),那么这一段的长度就是备选答案之一。
所以我们需要使用哈希来存储前缀和中每个数第一次出现的位置,当其又一次出现时,就可以计算长度作为备选答案。

要求平均数为k,预先让每个数减去k,则要求平均数为0,也就是这一段的和为0,可以使用前缀和遍历得到答案

#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=1e5+100;
typedef long long ll;
const int mod=1e9+7;
map<ll,int>mp; 
int n;
ll a[maxn],sum[maxn],k;
//sum[l,r]=k*len
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]-=k;
		sum[i]=(sum[i-1]+a[i]);
	}
	mp[0]=0;
	int ans=0;
	for(int i=1;i<=n;i++){
		if(mp.count(sum[i])){
			ans=max(ans,i-mp[sum[i]]);
		}else{
			mp[sum[i]]=i;
		}
		
	}
	cout<<ans<<endl;
	return 0;
} 
posted @ 2024-10-16 17:58  lipu123  阅读(8)  评论(0)    收藏  举报