• HUD—6287,口算训练,思维,素因子分解,lower_bound, upper_bound


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


     

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

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

    小Q迅速地回答了出来,但是小T并不知道正确答案是什么,请写一个程序帮助小T计算这些问题的正确答案。
     

    Input
    第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。

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

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

    接下来m行,每行三个正整数l,r,d(1≤l≤r≤n,1≤d≤100000),表示每个问题。
     

    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

    解析:

    我们可以将所有数字进行素因子分解,如 6 4 他们的乘积可以分解为2^3*3^1,而 24 同样可以备份分解为 2^3*3^1 显然,当询问的数字分解的素因子均存在与区间乘积的分解后的因子中,且区间乘积分解的任意因子的次幂均不小于询问的数字分解的素因子的次幂时,区间乘积就一定被所询问的数字整除

    但这里有一个难点:我们如何存储分解出来的素因子及其次幂,同时还能方便后续的查找呢?
    这里提供一个方法:vectorG[N]
    G[i] 内的信息表示素因子 i 出现的位置
    如: 6 4
    则 G[2]={1,2,2}   //素因子 1 出现在第一个位置,由于位置只有一个 1 个,所以在位置1只出现了一次;素因子 2 出现在第一个位置,由于位置只有一个 2 个,所以在位置 2 只出现了两次
       G[3]={1}          //素因子 3 出现在第一个位置,由于位置只有一个 1 个,所以在位置1只出现了一次

     

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. using namespace std;
    16. typedef long long LL;
    17. const int N = 1e5 + 5;
    18. int n,m;
    19. int a[N];
    20. int l, r, d;
    21. vector<int>G[N];
    22. void F(int t, int index) {
    23. for (int i = 2; i * i <= t; i++) {
    24. while (t % i == 0) {
    25. G[i].push_back(index);
    26. t /= i;
    27. }
    28. }
    29. if (t>1) {
    30. G[t].push_back(index);
    31. }
    32. }
    33. int main() {
    34. int T;
    35. scanf("%d", &T);
    36. while (T--) {
    37. scanf("%d%d", &n, &m);
    38. for (int i = 1; i < N; i++)G[i].clear();
    39. for (int i = 1,t; i <= n; i++) {
    40. scanf("%d", &t);
    41. F(t,i);
    42. }
    43. while (m--) {
    44. int flg = 0,cnt=0;
    45. scanf("%d%d%d", &l, &r, &d);
    46. for (int i = 2; i * i <= d; i++) {
    47. cnt = 0;
    48. while (d % i == 0) {
    49. d /= i;
    50. cnt++;
    51. }
    52. if (cnt) {//千万注意,不能少这个判断,否则会多出很多无意义的运行,回爆时间
    53. //lower_bound 返回一个迭代器,指向序列中不小于给定值的第一个元素。
    54. //upper_bound 返回一个迭代器,指向序列中大于给定值的第一个元素。
    55. int pp = upper_bound(G[i].begin(), G[i].end(), r) - lower_bound(G[i].begin(), G[i].end(), l);
    56. if (pp < cnt) {
    57. flg = 1;
    58. break;
    59. }
    60. }
    61. }
    62. if (d > 1) {
    63. int pp = upper_bound(G[d].begin(), G[d].end(), r) - lower_bound(G[d].begin(), G[d].end(), l);
    64. if (!pp) {
    65. flg = 1;
    66. }
    67. }
    68. if (flg) {
    69. printf("No\n");
    70. }
    71. else {
    72. printf("Yes\n");
    73. }
    74. }
    75. }
    76. return 0;
    77. }

  • 相关阅读:
    【中间件篇-Redis缓存数据库08】Redis设计、实现、redisobject对象设计、多线程、缓存淘汰算法
    Linux服务器,使用ssh登录时越来越慢,有时甚至出现超时的现象,解决方案
    小白入门深度学习 | 6-4:ResNet-50(2015年)详解
    Python --- 在python中安装NumPy,SciPy,Matplotlib以及scikit-learn(Windows平台)
    HybridApp(混合应用)开发框架的优缺点分析
    JDK各版本新增功能
    Linux删除文件与Python代码删除文件命令
    2023-09-04 Linux 让shell编译脚本里面设置的环境变量改变kernel里面驱动文件的宏定义值方法,我这里用来做修改固件版本
    【JavaSE】JavaSE之控制逻辑
    Centos - 磁盘快照
  • 原文地址:https://blog.csdn.net/Landing_on_Mars/article/details/133893938