HDOJ Problem - 1299

题意:等式 1 / x + 1 / y = 1 / n (x, y, n ∈ N+ (1) 且 x <= y) ,给出 n,求有多少满足该式子的解。(1 <= n <= 1e9)

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

分析:x,y肯定都满足 n<x<=y; 设 x = n + k; 带入上式得 :1/y = k/(n2+n*k); 即 k要整除 (n2+n*k); 又 k 一定整除 n*k; 即求 k 整除 n2; 即求 n2 的因数个数。

注意:   1.数据范围太大,不能直接分解n2

2.利用唯一分解定理的推论求因数个数:对于一个数n,由唯一分解定理得x=a1^k1*a2^k2...*an^kn.(ai为素数)。

则x的因子个数为(k1+1)*(k2+1)*...*(kn+1)。

    3.推出:x2=(a1^k1*a2^k2......*an^kn)2. 则 n2的因子个数为 (2*k1+1)*(2*k2+1)*......*(2*kn+1)。

    4.又x<=y, 则 ans=(ans+1)/2;(ans是n^2的因数个数)。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<cmath>
 6 using namespace std;
 7 #define ll long long
 8 #define mx 100000
 9 int prime[mx];
10 int vis[mx];
11 void getprime()
12 {
13     int m=sqrt(mx+0.5);
14     for(int i=2;i<=m;i++)
15     {
16         if(!vis[i])
17         {
18             for(int j=i*i;j<mx;j+=i)
19                 vis[j]=1;
20         }
21     }
22     int cnt=0;
23     for(int i=2;i<mx;i++)
24         if(!vis[i])
25            prime[cnt++]=i;
26 }
27 int fun(int num)
28 {
29     int ans=1;
30     int qs=sqrt(num+0.5);
31     //cout<<qs<<endl;
32     for(int i=0;prime[i]<=qs;i++) //设a=n+x,b=n+y。得到n^2=x*y
33     {
34         int cnt=0;
35         while(!(num%prime[i])&&num>1)
36         {
37             num/=prime[i];
38             cnt++;
39         }
40         ans*=(2*cnt+1);    //注意:由于n的范围比较大,所以我们不能直接将n^2分解,
41     }                      //我们可以通过分解n从而得知n^2分解的情况,由此计算答案
42     if(num!=1)
43         ans*=3;
44     return ans;
45 }
46 int main()
47 {
48    getprime();
49    int t;
50    scanf("%d",&t);
51    for(int k=1;k<=t;k++)
52    {
53        int n;
54        scanf("%d",&n);
55        int ans=fun(n);
56        printf("Scenario #%d:\n%d\n\n",k,(ans+1)/2);
57    }
58    return 0;
59 }
时间: 2024-08-15 06:52:10

HDOJ Problem - 1299的相关文章

HDU 4910 HDOJ Problem about GCD BestCoder #3 第四题

首先 m = 1 时 ans = 0对于 m > 1 的 情况 由于 1 到 m-1 中所有和m互质的数字,在 对m的乘法取模 运算上形成了群 ai = ( 1<=a<m && gcd(a,m) == 1 ) 所以 对于 a 必然存在b = a^(-1) = inv(a) 使得 a * b = 1 (mod m) 这里存在两种情况 a != b 那么最后的连乘式中a b均出现一次,相乘得1 a == b 那么最后的连乘式中只出现一个a 实际上所有 a = inv(a) 的

HDOJ Problem 1001

输入32位的有符号整数,求和SUM(n)的值. 1 #include <stdio.h> 2 3 int main(void) 4 { 5 int n,sum,i; 6 7 while(scanf("%d",&n) != EOF) 8 { 9 sum = 0; 10 11 for(i = 1;i <= n;i++) 12 sum += i; 13 printf("%d\n\n",sum); 14 } 15 16 return 0; 17 }

hihocoder 1299 打折机票 线段树

题目链接:http://hihocoder.com/problemset/problem/1299 code: //线段树 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 100005 using namespace std; int price[maxn]; int Max[maxn]; int segTree[4*maxn

Train Problem II

问题陈述: HDOJ Problem - 1023 问题解析: 卡特兰数(Catalan)的应用 基本性质: f(n) = f(1)f(n-1) + f(2)f(n-2) + ... + f(n-2)f(2) + f(n-1)f(1); f(n) = C(2n, n) / (n+1) = C(2n-2, n-1) / n;  Cn = (4n-2)/(n+1) Cn-1 代码详解: 1 #include <iostream> 2 #include <cstdio> 3 #inclu

[HIHO1299]打折机票(线段树)

题目链接:http://hihocoder.com/problemset/problem/1299 线段树,按照t为下标去更新v,更新的时候要保留最大的那个. 1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include

BZOJ1299 [LLH邀请赛]巧克力棒

怎么又是博弈论...我去 Orz hzwer,这道题其实是可以转化成Nim游戏的! "第一步: 先从n根巧克力棒中取出m(m>0)根,使得这m根巧克力棒的xor和为0,同时使得剩下的n-m根巧克力棒无论怎么取,xor和都不为0. m根巧克力棒的xor和为0 <=>把nim游戏的必败状态留给对方 剩下的n-m根巧克力棒无论怎么取,xor和都不为0 <=>  m为巧克力棒的xor和为0的最长子序列 第二步: 第一步以后,对手就面临一个必败状态的nim游戏. 如果他从n-

【HDOJ】3509 Buge&#39;s Fibonacci Number Problem

快速矩阵幂,系数矩阵由多个二项分布组成.第1列是(0,(a+b)^k)第2列是(0,(a+b)^(k-1),0)第3列是(0,(a+b)^(k-2),0,0)以此类推. 1 /* 3509 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #incl

【HDOJ 1002】A + B Problem II

A + B Problem II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 238517    Accepted Submission(s): 45969 Problem Description I have a very simple problem for you. Given two integers A and B, you

hdoj 1023 Train Problem II 【卡特兰】+【高精度】

题意:询问有多少种进站出站的顺序. 经典卡特兰.我对卡特兰目前的认识就是有n个1和n个-1,组成一个为2n的数列的方式有多少种.这就跟火车进站出站类似, 至于具体的卡特兰数的介绍,百度解释的很详细. 代码1(c语言): /* h(n) = h(n-1)*(4*n-2)/(n+1); */ #include <stdio.h> #include <string.h> #define M 110 int s[M][M] = {0}, b[M]; void init(){ s[1][0]