zoukankan      html  css  js  c++  java
  • 口算训练(唯一分解定理 + 二分+2018年女生赛)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6287

    题目:

    口算训练

    Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
    Total Submission(s): 177    Accepted Submission(s): 41


    Problem Description
    小Q非常喜欢数学,但是他的口算能力非常弱。因此他找到了小T,给了小T一个长度为n 的正整数序列a1,a2,...,an ,要求小T抛出m 个问题以训练他的口算能力。

    每个问题给出三个正整数
    l,r,d ,小Q需要通过口算快速判断al×al+1×...×ar1×ar 是不是d 的倍数。

    小Q迅速地回答了出来,但是小T并不知道正确答案是什么,请写一个程序帮助小T计算这些问题的正确答案。
     
    Input
    第一行包含一个正整数T(1T10) ,表示测试数据的组数。

    每组数据第一行包含两个正整数
    n,m(1n,m100000) ,分别表示序列长度以及问题个数。

    第二行包含
    n 个正整数a1,a2,...,an(1ai100000) ,表示序列中的每个数。

    接下来
    m 行,每行三个正整数l,r,d(1lrn,1d100000) ,表示每个问题。
     
    Output
    对于每个问题输出一行,若是倍数,输出Yes,否则输出No。
     
    Sample Input
    1
    5 4
    6 4 7 2 5
    1 2 24
    1 3 18
    2 5 17
    3 5 35
     
    Sample Output
    Yes
    No
    No
    Yes
     
    思路:如博客题目所言,唯一分解定理+二分。首先将所有的a进行素数分解,然后用一个vector记录这个素数出现的位置(如x % i == 0, 此时x 是第8位数,那么p[i].push_back(8)),然后二分从d分解出来的素数在该区间内出现总次数是否大于它在d中的次数。
    代码实现如下:
     1 #include <cstdio>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int maxn = 1e5 + 7;
     7 int t, n, m, l, r, d, x;
     8 
     9 vector<int> G[maxn];
    10 
    11 int check(int l, int r, int x) {
    12     return upper_bound(G[x].begin(), G[x].end(), r) - lower_bound(G[x].begin(), G[x].end(), l);
    13 }
    14 
    15 bool slove(int l, int r, int x) {
    16     for(int i = 2; i * i <= x; i++) {
    17         int cnt = 0;
    18         if(x % i == 0) {
    19             while(x % i == 0) {
    20                 cnt++;
    21                 x /= i;
    22             }
    23             if(cnt > check(l, r, i)) {
    24                 return false;
    25             }
    26         }
    27     }
    28     if(x > 1) {
    29         if(check(l, r, x) < 1) {
    30             return false;
    31         }
    32     }
    33     return true;
    34 }
    35 
    36 int main() {
    37     scanf("%d", &t);
    38     while(t--) {
    39         scanf("%d%d", &n, &m);
    40         for(int i = 0; i < maxn; i++) {
    41             G[i].clear();
    42         }
    43         for(int i = 1; i <= n; i++) {
    44             scanf("%d", &x);
    45             for(int j = 2; j * j <= x; j++) {
    46                 if(x % j == 0) {
    47                     while(x % j == 0) {
    48                         G[j].push_back(i);
    49                         x /= j;
    50                     }
    51                 }
    52             }
    53             if(x > 1) {
    54                 G[x].push_back(i);
    55             }
    56         }
    57         while(m--) {
    58             scanf("%d%d%d", &l, &r, &d);
    59             printf("%s
    ", slove(l, r, d) ? "Yes" : "No");
    60         }
    61     }
    62 }
  • 相关阅读:
    Linux下三个密码生成工具
    禁止root用户远程登录
    servlet/filter/listener/interceptor区别与联系
    linux top命令查看内存及多核CPU的使用讲述
    Django-MTV
    Python开发【前端】:jquery
    Python开发【前端】:JavaScript
    查看所有用户下的定时任务
    linux下如何查看哪些进程占用的CPU内存资源最多
    CentOS7 使用tab建补全命令
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9105038.html
Copyright © 2011-2022 走看看