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

CF1305C Kuroni and Impossible Calculation

题目大意

给定一个长度为 n 的数组,数组元素互不相同,输出所有满足 1 <= i < j <=n 的| a[i] - a[j] |的乘积对m取模后的结果。

题目分析

一开始可能没什么思路,想到暴力。但是,2e5的数据范围,用暴力的O(n^{2})肯定是无法做到的。

(对于数学比较好的同学,可以看一下这一段;但是,正解在这一段后面,此处只列出一种可能性)那么,我们对乘法的式子进行一下分析,发现,它符合范德蒙行列式:

那么,就可以考虑用FFT(快速傅里叶变换)或其他快速多项式算法,将时间复杂度压缩到O(nlogn),那么应该就能做了。

但是,作者数学不太好(恼),没有办法优化时间复杂度,那就只能优化数据范围了。

首先,对于数组a中的元素,如果存在任意 i ,j 满足| a[i] - a[j] |%m等于0,那么,不管其他情况如何,最终结果一定是0。所以,只要在输入的时候,判断一下,有没有两个元素对m取模后的结果相同(即,差为m的倍数)的情况,有则输出0,反之则暴力计算即可。

为什么加上这个条件,就可以暴力了呢?

注意到,任意一个数对m的取模结果必然在[0,m-1]区间内,也就是有m种可能性。那么,当数组大小n大于m时,必然存在一个值满足至少为两个数组元素取模后的结果,即存在i ,j 满足| a[i] - a[j] |%m等于0,那么最终答案一定为0。也就是说,我们只需要暴力运算 n < m 的情况,即把数据压缩到了1e3的范围,这个就可以用暴力的方法计算了。

代码实现

#include <iostream>
using namespace std;
int n, m, a[200010];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i = 0; i < n; i++)cin >> a[i];
    if (n > m)cout << "0";//如果n > m则答案为0,反之暴力运算
    else {
        long long ans = 1;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                ans = (ans * abs(a[i] - a[j])) % m;
            }
        }
        cout << ans;
    }
}


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

相关文章:

  • 现在集成大模型的IDE,哪种开发效率最高
  • 初识JavaFX-IDEA中创建第一个JavaFX项目
  • Project #0 - C++ Primer前置知识学习
  • ARM Coretex-M核心单片机(STM32)找到hardfault的原因,与hardfault解决方法
  • 算法题(79):两个数组的交集
  • seacmsv9注入管理员账号密码+order by+limit
  • MaxKB上架至阿里云轻量应用服务器镜像市场
  • 安科瑞为高速公路服务区充电桩建设运营提供解决方案
  • Canvas在视频应用中的技术解析
  • 国密算法Sm2工具类--golang实现版
  • SpringBoot项目连接Oracle视图报错整理
  • 上证50期权代码是什么?上证50股指期权数据从哪里可以找到?
  • 怎么获取免费的 GPU 资源完成大语言模型(LLM)实验
  • 在CentOS 7上安装RocketMQ 4.9.2
  • Vscode编辑器:解读文件结构、插件的导入导出、常用快捷键配置技巧及其常见问题的解决方案
  • 如何在Spring Boot中监控缓存的命中率?
  • 学习路之PHP --TP6异步执行功能 (无需安装任何框架)
  • HDFS扩缩容及数据迁移
  • 面试之《react hooks在源码中是怎么实现的?》
  • HIVE SQL函数之比较函数