Processing math: 100%

口算训练 - HDU 6287 - 唯一分解定理 + 二分查找

口算训练 - HDU 6287 - 唯一分解定理 + 二分查找

唯一分解定理

一个合数N可以展开成若干个质数幂相乘的形式。

N=pe11pe22...penn

一个数M如果是N的倍数,则M的分解式中对应的幂的指数都应不小于N

本题思路

本题检验alal+1al+2...ar1ard的倍数关系,只需要检验[l,r]区间分解质因数后各个质数的指数值与d对应的质数的指数值的大小关系。

我们可以预处理数组的质因数分解情况,记录每一个质数是由原数组中哪一个数分解得到的。

分解得到质因数的代码为

inline void decompose(int pos,int x,int arr[],vector<int> G[MaxN]){
  // (合数x在数组中的位置,合数x的大小,原数组,记录质数出现位置的变长数组)
    for (int i = 2; i * i <= x; i++) {
        while(x % i == 0){
            G[i].push_back(pos);
            x /= i;
        }
    }
    if(x > 1){
        G[x].push_back(pos);
    }
}

假设给定序列为 4,8,12,15,20

可以得到质数的出现情况

G[2] = <1,1,2,2,2,3,3,5,5>
G[3] = <3,4>
G[5] = <4,5>

我们可以得到,对于质数p,其在区间[l,r]出现的总个数为

int sum = upper_bound(G[p].begin(),G[p].end(),r) - lower_bound(G[p].begin(),G[p].end(),l);

代码

#include <cstdio>
#include <vector>
#include <algorithm>
#define MaxN 100000+5
using namespace std;

inline void decompose(int pos,int x,int arr[],vector<int> G[MaxN]){
    for (int i = 2; i * i <= x; i++) {
        while(x % i == 0){
            G[i].push_back(pos);
            x /= i;
        }
    }
    if(x > 1){
        G[x].push_back(pos);
    }
}


int main(){
    int t;
    scanf("%d",&t);
    while (t--) {
        int n,m;
        int arr[MaxN];
        int l,r,val;
        vector<int> G[MaxN];
        scanf("%d %d",&n,&m);
        for(int i = 1; i <= n; i++){
            scanf("%d",&arr[i]);
        }
        for(int i = 1; i <= n; i++){
            decompose(i,arr[i],arr,G);
        }
        while (m--) {
            bool flag = true;
            scanf("%d %d %d",&l,&r,&val);
            for(int i = 2; i * i <= val; i++){
                int cnt = 0;
                while (val % i == 0) {
                    cnt++;
                    val /= i;
                }
                if(cnt){
                    int sum = (int)(upper_bound(G[i].begin(),G[i].end(),r) - lower_bound(G[i].begin(),G[i].end(),l));
                    if(sum < cnt){
                        flag = false;
                        break;
                    }
                }
            }
            if(flag && val > 1){
                int sum = (int)(upper_bound(G[val].begin(),G[val].end(),r)-lower_bound(G[val].begin(),G[val].end(),l));
                if(sum == 0){
                    flag = false;
                }
            }
            
            if(flag)
                puts("Yes");
            else puts("No");
        }
    }
    return 0;
}

posted @   popozyl  阅读(155)  评论(0编辑  收藏  举报
编辑推荐:
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
阅读排行:
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用
点击右上角即可分享
微信分享提示