[2016-04-21]LightOJ][1341][Aladdin and the Flying Carpet]

  • 时间:2016-04-21 16:45:58 星期四

  • 题目编号:[2016-04-21]LightOJ][1341][Aladdin and the Flying Carpet]

  • 题目大意:

    • 给定数a,b,问满足c×d==a且bc,bd 二元组对数,
    • (c,d)和(d,c)是同种情况
    • c != d
  • 分析:

    • 分解a(唯一分解定理),n=p1a1+p2a2++piai+pnan
    • 求约数的个数 cnt=(a1+1)(a2+1)(ai+1)(an+1)
    • 因为不考虑c == d的情况,所以直接总的对数直接 n /= 2即可
  1. #include<cstdio>
  2. #include<cstring>
  3. using namespace std;
  4. const int maxn = 1E6 + 10;
  5. int pri[maxn + 1];
  6. void getPri(){
  7. memset(pri,0,sizeof(pri));
  8. for(int i = 2 ; i <= maxn ; ++i){
  9. if(!pri[i]) pri[++pri[0]] = i;
  10. for(int j = 1 ; j <= pri[0] && pri[j] <= maxn/i;++j){
  11. pri[pri[j]*i] = 1;
  12. if(i % pri[j] == 0) break;
  13. }
  14. }
  15. }
  16. long long fac[maxn][2];
  17. int fatcnt;
  18. int getFac(long long x){
  19. fatcnt = 0;
  20. long long tmp = x;
  21. for(int i = 1 ; pri[i] <= tmp/pri[i];++i){
  22. fac[fatcnt][1] = 0;
  23. if(tmp % pri[i] == 0){
  24. fac[fatcnt][0] = pri[i];
  25. while(tmp % pri[i] == 0){
  26. ++fac[fatcnt][1];
  27. tmp /= pri[i];
  28. }
  29. ++fatcnt;
  30. }
  31. }
  32. if(tmp != 1){
  33. fac[fatcnt][0] = tmp;
  34. fac[fatcnt++][1] = 1;
  35. }
  36. return fatcnt;
  37. }
  38. int main(){
  39. int t,cntcase = 0;
  40. scanf("%d",&t);
  41. getPri();
  42. while(t--){
  43. long long a,b;
  44. scanf("%lld%lld",&a,&b);
  45. if(a < b*b){
  46. printf("Case %d: %d\n",++cntcase,0);
  47. continue;
  48. }
  49. getFac(a);
  50. int cnt = 1;
  51. for(int i = 0; i < fatcnt ; ++i){
  52. cnt *= (fac[i][1]+1);
  53. }
  54. cnt /= 2;
  55. for(int i = 1; i < b ; ++i){
  56. if(a % i == 0) --cnt;
  57. }
  58. printf("Case %d: %d\n",++cntcase,cnt);
  59. }
  60. return 0;
  61. }


来自为知笔记(Wiz)


posted on 2016-04-21 17:01  红洋  阅读(140)  评论(0)    收藏  举报

导航