zoukankan      html  css  js  c++  java
  • 口算训练

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

    唯一分解定理

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

    (N = p_1^{e_1}p_2^{e_2}...p_n^{e_n})

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

    本题思路

    本题检验(a_l*a_{l+1}*a_{l+2}...*a_{r-1}*a_r)(d)的倍数关系,只需要检验([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;
    }
    
    
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    [APIO2018] Duathlon 铁人两项
    「PKUWC2018」随机游走
    「2018山东一轮集训」 Tree
    「2018山东一轮集训」Game
    [Lydsy1805月赛] quailty 算法
    CodeForces
    CodeForces
    「2018山东一轮集训」鸽子
    python序列化
    python的shutil模块
  • 原文地址:https://www.cnblogs.com/popodynasty/p/13638151.html
Copyright © 2011-2022 走看看