求大佬帮助!!!!!

计算机之猪 2024-10-13 13:53:06

题目描述

你现在有一堆正整数,这些正整数的数量为nn,并且数量为n依次排成一排。对于这些正整数 a1,a2,a3,…,ana1​,a2​,a3​,…,an​,它们的范围十分小。今天你突发奇想,想到了一些询问,对于这些询问:

  1. 每次给定两个整数 l,r,1≤l≤r≤nl,r,1≤l≤r≤n。

  2. 找到这个区间的最大值 mm。

  3. 统计 al,al+1,…,ar−1,aral​,al+1​,…,ar−1​,ar​ 中有多少个数满足 lcm(ai,m)=ai×mlcm(ai​,m)=ai​×m。这里 lcm(a,b)lcm(a,b) 表示 aa 和 b 的最小公倍数。

输入描述

第一行两个整数 n, q,依次表示整数的个数以及询问的次数。
第二行 n 个整数a1,a2,…,ana1​,a2​,…,an​。
接下来 q 行,每行两个正整数 li,rili​,ri​,表示询问的区间。

输出描述

输出qq行每行一个整数,表示每次查询的结果

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

// 计算最大公约数
int gcd(int a, int b) {
    if(a<b) swap(a,b);
    return (b==0?a:gcd(b,a%b));
}

// 找到区间[l, r]的最大值
int max_in_array(int * arr,int l,int r) {
    int * a2=arr;
    sort(a2+l-1,a2+r);
    return a2[r];
}

// 处理询问
int ask(int * arr,int l,int r) {
    int m=max_in_array(arr,l,r),s=0;
    for (int i=l;i<=r;++i)
    s+=bool(gcd(arr[i],m));
    return s;
}

int main() {
    int n=0,q=0;
    cin >> n >> q;
    int a[n]={};
    for (int i=0;i<n;i++)
    cin >> a[i];
    while (q--)
    {
        int l=0,r=0;cin >> l >> r;
        cout << ask(a,l-1,r-1) << endl;
    }
}

部分测试点依然显示超时,求大佬指点!!!!!!!!!!!!!!!!!!!!!!

...全文
201 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复

没有给定数据范围,不好说什么算法效率最高。
只说你的代码的问题:
一是gcd使用除法而且递归,效率很低。
二是求最大数m没必要sort,顺序扫描是O(n)算法,sort哪有O(n)呢,更糟糕的是sort可能改变输入序列,你的后续求解都是错的了。
实际上"满足 lcm(ai,m)=ai×m"这条件说明要么ai、m之一为1、要么其一为质数并且大数不能整除以小数(比如5、6),所以一个可能的优化是输入时就求出每个数是否质数并记录下来,但是如果数据范围很大的话这个方法不行(不过题目中说了“它们的范围十分小”)。

forever74 10-13
  • 举报
回复
@日立奔腾浪潮微软松下联想 嗯,14和15互质但它俩都是合数,最小公倍数是它们的积。
@forever74 嗯,是我考虑不全面。可以考虑:1、m为1则区间范围内全符合;2、ai为1则符合;3、二者皆为偶数不符合;3、二者皆为奇数判断是否互质数;4、一偶数一奇数则对偶数一直除以2转化为奇数然后参照3

65,108

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧