前缀和 求数列的子序列的K倍区间

news2024/10/6 18:25:50

(直接截图比复制文字要好多了)

不会做的时候我去看了之前做的关于这道题目的笔记,

(Ak + 1)% k == 1 (Ak + 1 + Ak)% k == 1

只要发现了同余数的情况就说明有一个区间满足了题目的要求。

这个方法的精妙之处就在于前缀和包括了之前的前缀和和下一个的数字之和(相邻的两个是这样的,如此一来,单个数字 % k == 0的就也能够被检查到了,就是把单个数组也看作了是一个区间。准确说是结合才对。

(这里还是建议去多举几个例子,去理解一下这句话的含义))

不清楚问题,我直接去看了题解

顺着这个思路其实很容易就能发现一个方法——求出那些个区间再使用排列组合,把可能的组合都用公式计算出来。(考虑到一些区间是断裂的,由(Ak + 1)% k == 1 (Ak + 1 + Ak)% k == 1想到,一种特殊的可能就是区间里面的所有数字都可以被k整除)  但是转念一想,不是所有的数都一定是k的整数倍。但是受到Ak + 1)% k == 1 (Ak + 1 + Ak)% k == 1的影响,我还是只考虑了单个元素,而忘了区间的概念,区间的组合是可以用排列组合来处理的。于是我想到了下面的一一对比的方法。

package 练习;

import java.util.*;

public class K倍区间 {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int N = scan.nextInt();
		int K = scan.nextInt();
		scan.nextLine();
		int number = 0;
		int[] sum = new int[N + 1];

		for (int i = 1; i <= N; i++) {
			sum[i] = scan.nextInt() + sum[i - 1];
			for(int j = 0; j < i; j++)
			    if(sum[i] % K == sum[j] % K) 
			       number ++;
			scan.nextLine();
		}
		
		System.out.println(number);
		
	}
}

我想不明白,为什么我这for循环里面的for都似乎只有条件满足才执行的,为什么还是超时了。难道不管执不执行,两个for循环都会消耗大量的时间。

就是如此——

if语句本身的时间复杂度是O(1),即常数时间复杂度,不受问题规模N的影响。这是因为每次执行if语句时,仅进行一次条件判断,其执行时间是固定的,不随N的增大而增大。

时间复杂度能忽略掉if条件判断的情况是,其时间复杂度远远超过了if语句造成的影响。但是,如果if的执行次数是整个程序的大头就不能忽略了

事实上

每一条Java语句,或者任何编程语言中的语句,都有其执行所需的时间成本,可以理解为占有一定的“时间复杂度”。

找到占大头的开销语句,在没有积累起一些反例之前,不要被具体的例子蒙蔽了双眼,去考虑书上那些容易被忽略的知识。if 和 for循环里面的的都有可能让你的时间复杂度暴增。

回到问题本身,我们不难发现,这个if语句的时间复杂度为

N * (1 + 2 + 3 + ... + N)
= N * (N * (N + 1)) / 2
= O(N^3 / 2)
≈ O(N^3)

这在蓝桥杯里面肯定是不可能被判定得分的。(除了数据特别少的情况下)

不成立的时候也总过有没有方法能和sum[ i ]的相同值,就像人脑一样,可以直接比较,看到了相同的数值就直接比较。但是计算机就是直接比较的,全部都要找一遍(for循环)但是又回到了原点。

最后我去看了题解,发现

#include<bits/stdc++.h>
using namespace std;
int n,k,a;
long long ans,sum,book[100005];
int main(){
	cin >> n >> k;
	book[0]++;  //把S0放进去,因为S0=0,所以给book[0]++
	for(int i=1;i<=n;i++){
		scanf("%d",&a);
		sum=(sum+a)%k; //sum是前缀和 也就是Si
		book[sum]++;
	}
	for(int i=0;i<k;i++)//注意 余数是0~m-1
		ans+=(book[i]*(book[i]-1))/2;
	cout << ans;
	return 0;
 } 
 //by chenhaotian0219

这里面的book[sum]吸引力我的注意。

这不就是映射吗,通过同余定理,把映射后的值域(0 < 数值 < k)设置数组也很方便,数值区间确定了,数组大小就不是问题了。(sun[ i ] % k == n == f (x) ),Y值域就是满足我们要求的,结合数组的特点就能够解决问题了。

数据结构里面的散列表就是这样被设计的。

这样字直接比较就做到了,for循环只是为了然所有的sum[ i ]都显现出来。

也看到了

#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,sum,p[1000001],n,k,ans;
signed main(){
    cin>>n>>k;
    p[0]=1;//定义初始值
    for(int i=1;i<=n;i++){
        cin>>a;
        sum+=a;
        sum%=k;
        p[sum]++;//对应余数的个数加一
    }
    for(int i=0;i<k;i++){
        ans+=(p[i]*(p[i]-1)/2);//从n个数里面选两个,共有n*(n-1)/2种选法。
    }
    cout<<ans;
    return 0;
}
for(int i=0;i<k;i++){
        ans+=(p[i]*(p[i]-1)/2);//从n个数里面选两个,共有n*(n-1)/2种选法。
    }

这格代码看起来很突兀,其实是我一开始的排列组合思考的排列组合,但是这里的是区间的。(最后这个for循环是从0开始的,指的是多格倍数部分,不是一个区间的)

单个区间的已经被计算过了(x),那么 a1 、 a2、a3 ... an 那么就是 n - 1 + n -2 + n - 3 + .. + 3 + 2 + 1(最后一个没有在里面,你把数字和个数一一对应就可以验证这个结论)。或者你这样子想——其实相互比较多是相邻的两个的sum[ i ]比较,组合就是跨国几个,还是两两比较。

一些无关的


签注和 —— 数列的和,如果你熟读数学,那么你可能就会独立发现这个算法。这就是数学的奥秘。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1621438.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

窗函数的选择

不同的窗函数实质上时对矩形窗进行了不同程度的加权得到的不同类型的窗函数。 将模拟角频率转换为了数字角频率 矩形窗旁瓣过大&#xff0c;两个频率的峰值相差较大&#xff0c;因此无法识别&#xff0c;可以使用旁瓣非常小的窗函数来进行分辨&#xff0c;只是想要达到相同的分…

目标检测——小麦穗头数据集

一、重要性及意义 小麦穗头检测在农业领域具有重要意义&#xff0c;主要体现在以下几个方面&#xff1a; 首先&#xff0c;小麦穗头检测可以帮助农民和植物科学家准确评估作物的健康状况和成熟度。通过对小麦穗部的形态特征进行测量和分析&#xff0c;可以及时发现作物生长过…

简单工厂、工厂方法、抽象工厂对比

简单工厂、工厂方法和抽象工厂是三种常见的工厂设计模式&#xff0c;它们在软件设计中各有其独特的应用场景和优缺点。因为三种设计模式都属于工厂模式&#xff0c;在实际应用中可能存在误用的场景&#xff0c;这里对其做下对比&#xff0c;以便更好的理解这三种设计模式。 简…

第四百七十七回

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性 3. 示例代码4. 内容总结 我们在上一章回中介绍了"Get包简介"相关的内容&#xff0c;本章回中将介绍GetMaterialApp组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经…

【HTML】页面引用Vue3和Element-Plus

在现代前端开发中&#xff0c;Vue 3 和 Element Plus 是非常受欢迎的技术。Vue 3 是一个用于构建用户界面的渐进式 JavaScript 框架&#xff0c;而 Element Plus 是一个基于 Vue 3 的组件库&#xff0c;提供了丰富的 UI 组件&#xff0c;帮助开发者快速构建高质量的前端应用。 …

【Java | 多线程】LockSupport 的使用和注意事项

了解一下 LockSupport LockSupport是一个类&#xff0c;位于java.util.concurrent.locks包中&#xff0c;提供了基本的线程同步机制。 LockSupport的主要作用是挂起和唤醒线程。它提供了两个主要的静态方法&#xff1a;park()和unpark()。 park()&#xff1a;用于挂起当前线…

成都百洲文化传媒有限公司电商服务怎么样?

在当今数字化浪潮席卷全球的背景下&#xff0c;电商行业异军突起&#xff0c;成为连接消费者与品牌之间的重要桥梁。在这股变革之风中&#xff0c;成都百洲文化传媒有限公司以其专业的电商服务&#xff0c;成为行业的佼佼者&#xff0c;助力众多品牌踏上腾飞之路。 一、专业铸…

【Java 解析全国详细地址】Java 利用正则表达式完美解析全国省市区地址

这里写自定义目录标题 Java使用正则解析省市区/县 具体地址问题场景上demo运行结果 Java使用正则解析省市区/县 具体地址 问题场景 OCR识别营业执照 获取详细地址并拆分 上demo import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import j…

前端开发攻略---封装calendar日历组件,实现日期多选。可根据您的需求任意调整,可玩性强。

1、演示 2、简介 1、该日历组件是纯手搓出来的&#xff0c;没依赖任何组件库&#xff0c;因此您可以随意又轻松的改变代码&#xff0c;以实现您的需求。 2、代码清爽干净&#xff0c;逻辑精妙&#xff0c;您可以好好品尝。 3、好戏开场。 3、代码&#xff08;Vue3写法&#xff…

ROS下机器人系统仿真及部分SLAM建图

文章目录 一、 Launch文件使用二、 参考资料三、 遇到的问题四、 效果演示五、相关代码5.1 一些简介5.2 机器人模型5.2.1 机器人底盘5.2.2 摄像头5.2.3 雷达 5.3 惯性矩阵 六、代码传送门实验结果及分析 温馨提示&#xff1a;如果有幸看到这个文章&#xff0c;不要看里面的内容…

bugku-杂项-社工进阶收集

下载附件 得到图片 利用百度地图查找 这里得到地点名称大雁塔音乐喷泉 陕西省西安市&#xff0c;大雁塔北广场 打开高德地图 来到大雁塔北广场 因为在北广场&#xff0c;所以地铁站为大雁塔站 开始分析 坐七站到大雁塔站&#xff0c;即始发站为韦曲南站 因为始发站离她家800米&…

Vue3的监听属性watch和计算属性computed

监听属性watch 计算属性computed 一、监听属性watch watch 的第一个参数可以是不同形式的“数据源&#xff0c;watch 可以监听以下几种数据&#xff1a; 一个 ref (包括计算属性)、 一个响应式对象、 一个 getter 函数、 或多个数据源组成的数组 watch 的参数:监视的回调&…

如何用stata画出文献中常见的安慰剂检验图?如何解决

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

Twisted 与 Tornado 中的 WebSocket 连接问题及解决方案

1、问题背景 项目中我们需要通过 Tornado HTTP 处理程序建立WebSocket连接&#xff0c;该连接需要处理多个用户请求&#xff0c;并且将从外部服务器获取的数据存储到数据库中。我们尝试了以下实现&#xff1a; from twisted.internet import reactor from autobahn.websocket…

R可视化:ggplot2绘制双y轴图

介绍 ggplot2绘制双y轴图加载R包 knitr::opts_chunk$set(message = FALSE, warning = FALSE) library(tidyverse) library(readxl)# rm(list = ls()) options(stringsAsFactors = F) options(future.globals.maxSize = 10000 * 1024^2)Importing data 下载Underdetection of c…

【性能测试】ChaosTesting(混沌测试)ChaosBlade(混沌实验工具)(六)-servelt

7. servelt接口规范 7.0 创建servelt blade create servlet 7.0.1 介绍 Servlet 是 Java 的 web 的接口规范&#xff0c;Java web 服务器都遵循此规范实现。本场景主要模拟 Java Web 请求延迟、异常场景。 [blade create servlet delay](blade create servlet delay.md) 请…

【网安小白成长之路】9.sql注入操作

&#x1f42e;博主syst1m 带你 acquire knowledge&#xff01; ✨博客首页——syst1m的博客&#x1f498; &#x1f51e; 《网安小白成长之路(我要变成大佬&#x1f60e;&#xff01;&#xff01;)》真实小白学习历程&#xff0c;手把手带你一起从入门到入狱&#x1f6ad; &…

Vue:vue的工程化

Vue前端工程化 前后端分离开发 即前端人员开发前端工程,将开发好的前端工程打包部署在前端服务器上 后端开发人员开发后端工程,再将后端工程打包部署在后端服务器上,这种模式称为前后端分离开发 而前后端要顺利对接的关键就是要遵循一定的开发规范 开发规范 这种开发规范定…

STC8H8K64U I2C主机模式相关寄存器

STC8H8K64U I2C主机模式相关寄存器 STC8H8K64U-TSSOP20 I2CCFG I2C配置寄存器 I2CMSCR I2C主机控制寄存器 I2CMSST I2C主机状态寄存器 I2CMSAUX I2C主机辅助控制寄存器 I2CTXD I2C数据发送寄存器 I2CRXD I2C数据接收寄存器 I2CCFG I2C配置寄存器 B7ENI2C ENI2C&#xff1a…

【题解】NowCoder DP4 最小花费爬楼梯

题目来源&#xff1a;牛客 DP4 最小花费爬楼梯 题目描述&#xff1a; 给定一个整数数组 cost &#xff0c; 其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用&#xff0c;下标从 0 开始。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从…