zoukankan      html  css  js  c++  java
  • lightoj 1341

    lightoj 1341  Aladdin and the Flying Carpet

    链接http://lightoj.com/volume_showproblem.php?problem=1341

    题意:给定整数 a, b ,求 区间[b, a] 内的 a 的约数对的个数,a 的约数对(比如[2, 3] 与 [3, 2] 是同一对),也就是说前因子要小于后因子。

    思路:我的思路比较直接,就是求 a 的约数的个数(用欧拉函数),除以 2 就得到约数对数, 然后暴力求解区间 [1, b] 内的 a 的约数。最后两数相减得到结果。

    代码

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <algorithm>
     4 #include <queue>
     5 #include <map>
     6 #include <set>
     7 #include <vector>
     8 #include <cstring>
     9 #include <math.h>
    10 using namespace std;
    11 
    12 typedef long long LL;
    13 const int maxv = 1000005;
    14 bool nu[maxv];
    15 int phi[80000], k;
    16 
    17 void prime()        //素数表
    18 {
    19     memset(nu, 0, sizeof(nu));
    20     int i, j;
    21     k = 1;
    22     nu[4] = 1, phi[0] = 2;
    23     for(i = 3; i < maxv; i += 2)
    24     {
    25         if(!nu[i])    phi[k++] = i;
    26         for(j = 0; j < k && i * phi[j] < maxv; j++)
    27         {
    28             nu[i*phi[j]] = 1;
    29             if(!(i % phi[j]))    break;
    30         }
    31     }
    32 }
    33 
    34 LL gain_ans(LL a)        //得到区间[1, a] 的约数对数
    35 {
    36     int i = 0, j;
    37     LL s = 1;
    38     if(a == 0)        return 0;
    39     while(phi[i] < a && i < k )    //欧拉函数
    40     {
    41         j = 0;
    42         if(a % phi[i] == 0)
    43             while(a % phi[i] == 0)
    44                 a /= phi[i], j++;
    45         s *= (j+1);
    46         i++;
    47     }
    48     if(a != 1)    s *= 2;
    49     return s / 2;
    50 }
    51 
    52 int main()
    53 {
    54     LL  b, a, s, q;
    55     int t, cs = 1;
    56     prime();
    57     freopen("lightoj1341.txt", "r", stdin);
    58     cin >> t;
    59     while(t--)
    60     {
    61         scanf("%lld%lld", &a, &b);
    62         q = 0;
    63         if(b >= sqrt(a))    s = 0;        // b 大小限定 
    64         else
    65         {
    66             q = 0;
    67             for(int i = 1; i < b; ++i)    //暴力枚举 [1, b] 的a 的约数
    68                 if(a % i == 0)    q++;
    69             s = gain_ans(a) - q;
    70         }
    71         printf("Case %d: %lld
    ", cs++, s);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    ASCII码对照表
    有种美叫做放弃
    OCX和DLL的区别
    江湖经验:喝酒的学问技巧
    TC2.0实现多文件编译
    希尔排序
    CalcOpticalFlowPyrLK的使用(转)
    简单选择排序的实现
    VS2008中解决方案窗口的问题
    用友T3用友通行政单位没有损益类科目,如何做期间损益结转?
  • 原文地址:https://www.cnblogs.com/Duahanlang/p/3222497.html
Copyright © 2011-2022 走看看