当前位置: 首页 > article >正文

k倍区间(蓝桥杯 )

题目描述

给定一个长度为 NN 的数列,A1,A2,⋯ANA1​,A2​,⋯AN​,如果其中一段连续的子序列 Ai,Ai+1,⋯AjAi​,Ai​+1,⋯Aj​ ( i≤ji≤j ) 之和是 K 的倍数,我们就称这个区间 [i,j] 是 K 倍区间。

你能求出数列中总共有多少个 KK 倍区间吗?

输入描述

第一行包含两个整数 N 和 K( 1≤N,K≤10 1≤N,K≤10 )。

以下 N 行每行包含一个整数 AiAi​ ( 1≤Ai≤10^{5}^{}1≤Ai​≤10^{5} )

输出描述

输出一个整数,代表 K 倍区间的数目

输入输出样例

示例

输入

5 2
1
2
3
4
5

输出

6

 首先想到的是暴力for(for()),两个数组去求,先从第一个数开始,加到最后一个,再从第二个开始,加到最后一个。问题就是会超时。

 

这个算法利用的是前缀和的知识,每一项都加上前一项,直到最后一项,求出所有的前缀和

从i>0开始,

求出每一项加上前一项的前缀和,

求出次和模的余数,将余数作为数组的下标,求出所有余数数量

用到一个重要知识点:任何两个前缀区间的和对k取模的值相等,则由大的前缀区间减掉小的前缀区间所形成的区间的必定是K倍区间(在官网上看到的题解,感觉思路很好)

任何两个前缀区间的个数\displaystyle C_{n}^{2}=(n*(n-1))/2,n=res[i];

注:1.不要忘记a[0],也要进行取模,res++;

2.类型要用 long long 

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+100;
typedef long long int ll;
int main()
{
  // 请在此输入您的代码
  int n,k;
  cin>>n>>k;
  ll a[N];
  ll sum=0;
  ll res[N]={0};
  for(int i=0;i<n;i++)
  {
    cin>>a[i];
    if(i>0){
      a[i]+=a[i-1];//求和
    }
    res[a[i]%k]++;
  }
  sum=res[0];
  for(int i=0;i<k;i++)
  {
    sum+=(res[i]*(res[i]-1))/2;
  }
  cout<<sum;
  return 0;
}

 


http://www.kler.cn/a/573327.html

相关文章:

  • 【AGI】智谱开源2025:一场AI技术民主化的革命正在到来
  • < 自用文儿 > DELETED 设置速读 in Ubuntu24
  • 游戏引擎学习第132天
  • 神经网络入门:分类与回归(3)
  • 充电桩测试负载应用:保障充电安全与性能的核心技术
  • SpringBoot 多环境配置
  • ChatGPT付费创作系统V3.1.3独立版 WEB端+H5端+小程序端 (新增DeepSeek高级通道+新的推理输出格式)
  • C#核心笔记——(四)C#高级特性
  • C语言高性能交换两个变量的值
  • 【蓝桥杯】每天一题,理解逻辑(2/90)【LeetCode 复写零】
  • Electron桌面应用开发:自定义菜单
  • 谈谈单例模式中通过Htools包的SpringUtil.getBean获取Bean的好处
  • 计算机毕业设计SpringBoot+Vue.js科研工作量管理系统的(源码+文档+PPT+讲解)
  • 在Linux中开发OpenGL——检查开发环境对OpenGL ES的支持
  • 【音视频】封装格式与音视频同步
  • 【Elasticsearch】reindex
  • ArcGIS操作:14 按位置选址
  • 深入解析 Android Activity 生命周期
  • 1、语言的本质
  • vue3中Element-plus table 反选 禁用实战