k倍区间

文章介绍了如何使用前缀和和组合数学的方法来解决给定数列中K倍区间的问题,避免了暴力枚举带来的超时问题,重点在于余数的统计和公式应用。
摘要由CSDN通过智能技术生成

题目

给定一个长度为 N 的数列,A1,A2,⋯AN,如果其中一段连续的子序列 Ai,Ai+1,⋯Aj ( i ≤ j ) 之和是 K 的倍数,我们就称这个区间 [ i, j ] 是 K 倍区间,求出数列中总共有多少个 K 倍区间

输入:
5 2
1
2
3
4
5

输出:
6

思路

直接暴力枚举的会超时,所以要设置a数组,a[i]表示从第一项到第i项的数组之和,a[i]-a[j]就吧表示 i-j 区间,(a[i]-a[j])%K == 0表示K倍区间,那么等价于a[i]%K ==a[j]%K(注意i,j 表示的是从第一到第 i 或者 j的区间,与就是两个区间和的余数相等),那么其总共是统计所有余数相等的两个数的组合(高中数学, 然后加上单个的数

代码

#include <iostream>
using namespace std;
int main()
{
  long long N,K,i,j,k;//使用long long防止溢出 
  long long cnt[100000] = {0};统计不同余数的多少 
  long count = 0;//k倍区间的和 
  long long a[100000] = {0};
  cin>>N>>K;
  for(i = 0;i < N;i++)
  {
  	cin>>a[i]; // 输入 
  	a[i] = (a[i-1] + a[i]);//表示从第一项到第i项的数组之和
  	cnt[a[i]%K]++;//统计不同余数的多少 
  }
  for(i = 0;i < N;i++)
  {
  	count = (cnt[i]*(cnt[i]-1))/2+count;//利用高中组合的公式 
  }
  count = count+cnt[0];//加上单个的数 
  cout<<count;//输出 
  return 0;
}
  • 总结:运用前缀和+组合数学的方法解决问题,也可以用暴力枚举(比赛的时候,当没有思路的时候可以先使用,拿到部分分数,之后再思考),重点是公式的推导和利用公式解决问题
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值