【CSP】2021-12-2 序列查询新解 分段处理 用乘法代替加法减少时间复杂度(思想是离散化)

news2025/1/16 18:06:32

2021-12-2 序列查询新解 分段处理 用乘法代替加法减少时间复杂度(思想是离散化)2021-12-2 序列查询新解 分段处理 用乘法代替加法减少时间复杂度(思想是离散化)

  • 2021-12-2 序列查询新解 分段处理 用乘法代替加法减少时间复杂度(思想是离散化)
    • 思路
    • 解题过程
    • 超时的完整代码
    • 100分的完整代码

2021-12-2 序列查询新解 分段处理 用乘法代替加法减少时间复杂度(思想是离散化)

这个题目挺有意思,比之前几年我做过的都要有些难,但是也不是难吧,就是没有见过这种的,然后就想不到怎么去优化时间复杂度。

一开始我以为题目的优化思路是预处理,就是提前算好f和g然后再减在一起算出sum,我还抱着侥幸心理,以为 1 0 9 10^9 109的复杂度不会超时,但是最后还是超时了,此时我就是黔驴技穷了,我只是想到在 1 0 9 10^9 109的基础上优化,但是没有想到怎么用直接使用 1 0 5 10^5 105分段进行计算。然后看了别人的思路才有了思路。希望考试不要出现这种情况,因为考试可没有别人的思路给你看。

思路

这题的思路不同于之前的第二题,实用什么的差分啊,什么二分搜索啊,什么动态规划啊都没有使用到。而是不同寻常的使用了分段的思想。

我一开始的想法是使用一个数组把f全部算出来,但是发现并不行会超时,并且也没有用空间来换取时间,但是其中有很多重复的加法,可以用乘法替换。

我们拿到一个问题一般是要将问题规约成更小的问题,那么如何规约就会导致问题的时间复杂度和空间复杂度不同,这题你要是想用空间换时间(就是把临时搜索的数据存储下来,后边可以不搜索直接使用的思想)不太行,而是要减少计算的次数,基本就是将加换成乘。

那么怎么将加换成乘呢?就是将相同的加合并,对应这个题目就是算f和g的时候,我们可以把一段区间内的加变成一次乘法。 那么这个区间就是当g和f 相同的区间,g的变化是有规律的,f 的变化也是有规律的,我们就是判断一个区间是不是f和g都不变化那么我们就可以直接加上区间长度和 ∣ f − g ∣ |f-g| fg​的乘积 。

解题过程

  1. 我首先就是按照我想的那种思路写了一种代码,直接就70分了,剩下全部超时了

在这里插入图片描述

  1. 然后我就想找一种优化的方法,比如使用常数级优化,O2优化等,全都是超时,可以发现只要 复杂度是 1 0 9 10^9 109​怎么优化也没有用的。

    测试只有一个for循环 1 0 9 10^9 109次什么也不干,就会超时

    在这里插入图片描述

  2. 然后看了别人的思路,说使用分段的思想,我瞬间就明白了,就写代码

在这里插入图片描述

但是发现错误不太行,原来是没有使用long long

改用了long long 后就可以了
在这里插入图片描述

超时的完整代码

#include <bits/stdc++.h>
using namespace std;
int n, N;
int a[100001];
int f[100000001];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> N;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    int top = 1;
    int r = N / (n + 1);
    long long sum = 0;
    for (int i = 0; i < N; ++i)
    {
        if (i < a[top])
        {
            f[i] = top - 1;
        }
        else
        {
            f[i] = top;
            if (top < n)
                top++;
            else
            {
                sum += abs(i / r - top);
                continue;
            }
        }
        sum += abs(i / r - f[i]);
    }
    cout << sum;
    return 0;
}

100分的完整代码

#include <bits/stdc++.h>
using namespace std;
int n, N;
int a[100001];
int main()
{
    cin >> n >> N;
    int maxa = -1;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        maxa = max(a[i], maxa);
    }
    int r = N / (n + 1);
    int f = 0;
    long long sum = 0;
    for (int i = 1; i <= n; i++)
    {
        // 判断g和f谁先变
        // f是遇到元素才变 g是隔r个数就变的
        f = i - 1;
        int length = a[i] - a[i - 1];
        int gl = a[i - 1] / r;
        int gr = (a[i] - 1) / r; // 不包括右端点,因为右端点f的值已经变化了
        if (gr == gl)            // 如果这个区间g的值没有变化
        {
            sum += abs(f - gl) * length;
        }
        else // 如果g有变化那么再分区间
        {
            int left = a[i - 1]; // 不断更新区间的左端点 知道超过f不变的区间
            while (left < a[i])
            {
                int length = min(a[i], (gl + 1) * r) - left;
                sum += abs(f - gl) * length;
                // 更新状态
                left = (gl + 1) * r;
                gl++;
            }
        }
    }
    if (maxa < N) // 遍历超出了a的数,此时f恒等于n g还是原来的变化规律
    {
        int f = n;
        int left = a[n];
        int gl = left / r;
        while (left <= N)
        {
            int length = min(N, (gl + 1) * r) - left;
            sum += abs(f - gl) * length;
            // TODO:更新状态
            left = (gl + 1) * r;
            gl++;
        }
    }
    cout << sum;
    return 0;
}

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

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

相关文章

1435A/B-V信号发生器

1435A/B-V 信号发生器 高兼容性 高输出功率 高灵敏度 1435-V系列信号发生器是一款性能优良的矢量信号发生器&#xff0c;频率范围覆盖9kHz&#xff5e;6GHz&#xff0c;200MHz内部调制带宽和齐全的数字调制样式&#xff0c;可满足各种宽带数字调制信号的模拟需求。 PART.0…

2024年3月份实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】

首先&#xff0c;来看下效果图 在线体验地址&#xff1a;https://geojson.hxkj.vip&#xff0c;并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据&#xff0…

1.1计算机系统构成及硬件系统知识(上)

基础知识部分----chap01 主要议题&#xff1a; 数制转换&#xff1a;一般会涉及存取的计算&#xff1b;ip地址中变长子网掩码的计算题&#xff1b;&#xff08;难度较大&#xff09; 数的表示&#xff1a;二进制、十六进制&#xff1b; 计算机的组成&#xff1a;考察的较为深入…

MySQL用法---MySQL Workbench创建数据库和表

1. 连接数据库 打开软件&#xff0c;点击左下角卡片&#xff0c;输入设置的数据库密码&#xff0c;勾选单选框 2. 了解主页面的组成部分 3. 创建数据库 先点击工具栏的创建按钮 再输入数据库名称 点击 Apply 创建 4. 创建数据表 展开数据库&#xff0c;在Tables上右键&…

数安委新栏目-微型发布会!首期推荐-天空卫士数据安全扫描仪(DSS)

新年伊始&#xff0c;CCIA数安委推出新栏目-微型发布会。天空卫士数据安全扫描仪&#xff08;DSS&#xff09;作为首期推荐产品&#xff0c;亮相新栏目。 点击可“阅读原文”&#xff1a;《微型发布会/数据安全扫描仪&#xff08;DSS&#xff09;-2024年第1期》。 为鼓励委员单…

支付模块-基于消息队列发送支付通知消息

消息队列发送支付通知消息 需求分析 订单服务作为通用服务&#xff0c;在订单支付成功后需要将支付结果异步通知给其他对接的微服务&#xff0c;微服务收到支付结果根据订单的类型去更新自己的业务数据 技术方案 使用消息队列进行异步通知需要保证消息的可靠性即生产端将消息…

git commit --amend

git commit --amend 1. 修改已经输入的commit 1. 修改已经输入的commit 我已经输入了commit fix: 删除无用代码 然后现在表示不准确&#xff0c;然后我通过命令git commit --amend修改commit

Python语言基础与应用-北京大学-陈斌-P40-39-基本扩展模块/上机练习:计时和文件处理-给算法计时-上机代码

Python语言基础与应用-北京大学-陈斌-P40-39-基本扩展模块/上机练习&#xff1a;计时和文件处理-给算法计时-上机代码 # 基本扩展模块训练 给算法计时 def factorial(number): # 自定义一个计算阶乘的函数i 1result 1while i < number:result result * ii 1return(resul…

推动新质生产力,机器人技术的黄金时代——张驰咨询

在这个不断进步和变化的时代中&#xff0c;张驰咨询与各个行业的领先企业紧密合作&#xff0c;致力于构建新一代生产力的未来蓝图。张驰咨询深刻理解各个行业的发展态势与独特性&#xff0c;通过深入分析企业遇到的挑战&#xff0c;张驰咨询提供定制化的解决方案&#xff0c;旨…

【代码随想录 | 数组 01】二分查找

文章目录 1.二分查找1.1题目1.2思路&#xff08;核心&#xff1a;区间的定义&#xff09;1.3左闭右闭1.4左闭右开1.5总结 1.二分查找 1.1题目 704.二分查找—力扣题目链接 题目&#xff1a;给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 …

Java毕业设计-基于spring boot开发的实习管理系统-毕业论文+答辩ppt(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1.开发说明2.需求分析3、系统功能结构 三、系统实现展示1、前台功能模块2、后台功能模块2.1 管理员功能2.2 教师功能2.3 学生功能2.4 实习单位功能 四、毕设内容和源代码获取总结 Java毕业设…

外贸产品再好,推广不出去也白搭!

外贸产品虽然质量和价格都很好&#xff0c;但是如果没有推广的支持&#xff0c;就很难在市场上打开局面。好的产品需要好的营销&#xff0c;推广不仅仅是宣传产品的重要手段&#xff0c;更是提高产品知名度和市场占有率的关键。只有通过有效的推广措施&#xff0c;才能让产品赢…

(Linux学习九)管道、重定向介绍

FD:文件描述符。 0,1,2,3&#xff0c;&#xff0c;&#xff0c;。进程打开文件所用。 0标准输入 1 标准输出 2 标准错误输出 3普通文件 一、管道 | 命令 | tee | xargs | 命令1的输出&#xff0c;作为命令2的输入&#xff0c;命令2的输出作为命令3的输入 | tee 三通&#xff…

【Python】random库

专栏文章索引&#xff1a;Python 原文章&#xff1a;Python中random函数用法整理_python random-CSDN博客 目录 1.random.random() 2.random.uniform(a, b) 3.random.randint(a, b) 4.random.randrange([start], stop[, step]) 5. random.choice() 6. random.shuffle(x[,…

工业园区智慧水电设备管控系统

在现代工业园区中&#xff0c;水电设备的管控系统起着至关重要的作用。这些系统不仅仅是简单的机械装置&#xff0c;它们更是一种智慧的结合&#xff0c;为工业生产提供了可靠的保障和高效的管理。让我们一起来探索工业园区智慧水电设备管控系统的奥秘。 我们来看看水电设备的…

电脑内存条

目录 一&#xff0c;电脑内存条是什么1&#xff0c;定义2&#xff0c;作用 二&#xff0c;怎样查看自己电脑内存条1&#xff0c;window运行管理器2&#xff0c;软件3&#xff0c;intel官网4&#xff0c;计算机命令行模式 三&#xff0c;选择电脑内存条1&#xff0c;选择ddr2&am…

如何在WordPress网站上设置多语言展示

在今天的全球化世界中&#xff0c;拥有多语言网站对于吸引更广泛的受众至关重要。前不就我们遇到Hostease的客户咨询我们的在线客服&#xff0c;他想要对他的wordpress网站支持多语言。我们提供给客户可以尝试以下的插件来支持多语言。 在本教程中&#xff0c;我们将逐步介绍如…

蓝桥杯-Python组(一)

1. 冒泡排序 算法步骤&#xff1a; 比较相邻元素&#xff0c;如果第一个大于第二个则交换从左往右遍历一遍&#xff0c;重复第一步&#xff0c;可以保证最大的元素在最后面重复上述操作&#xff0c;可以得到第二大、第三大、… n int(input()) a list(map(int, input()…

a-table:实现跨域多选功能——基础积累

table组件跨页多选功能&#xff1a; html部分的代码&#xff1a; <a-tablesize"small"style"margin-top: 10px"rowKey"id":columns"columns":dataSource"dataSource":pagination"pagination":loading"l…

从菜鸟到大师!年薪20W的c++ QT开发工程师需要懂哪些技术?

如今Qt的知识也变得非常广泛和复杂&#xff0c;学习起来同样具有一定的挑战。对于Qt从业者来说&#xff0c;有两个主要层面&#xff1a;一个是深入理解Qt框架和基础知识&#xff0c;另一个是具备丰富的工程经验。 还不熟悉的朋友&#xff0c;这里可以先领取一份Qt开发必备技术…