Question link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4983
Give N and K to find the conditions that meet
Gcd (n? A, n) × gcd (n? B, n) = NK .
A and B.
First, we can obtain the gcd (n, x) <n, so when K is greater than 2, there is no solution. When k is equal to 2, A = n, B = n to get n ^ 2, only one group.
N = 1.
This was the first time I thought about this question. Divide a number into a prime factor.
/* ===================================================== === The prime factor is decomposed into a positive integer, input: N output: Tot number of different prime factors a [] represents the complexity of the number of I prime factors: O (SQRT (n )) ========================================================== = */# define maxn 1111int A [maxn], B [maxn], TOT = 0; void factor (int n, int A [], int B [], Int & ToT) {int TMP, now; TMP = (INT) (SQRT (n) + 1); Tot = 0; now = N; For (INT I = 2; I <= TMP; I ++) if (now % I = 0) {A [tot] = I, B [tot ] = 0; while (now % I = 0) {B [tot] ++; now/= I;} tot ++;} If (now! = 1) A [tot] = now, B [tot ++] = 1 ;}
For example, 800 can be divided into 2 ^ 5*5 ^ 2, and the approximate number can be obtained based on the obtained quality factor:
1 |
800 |
2 |
400 |
4 |
200 |
8 |
100 |
16 |
50 |
32 |
25 |
5 |
160 |
10 |
80 |
20 |
40 |
40 |
20 |
80 |
10 |
160 |
5 |
25 |
32 |
50 |
16 |
100 |
8 |
200 |
4 |
400 |
2 |
800 |
1 |
For each appointment: for example ~ In 800, the number of dikes with the 800 public divisor 2 is: Euler (800/2 = 400,
For example, in this group: 5*160 = 800 in 1 ~ In 800, the number of public approx. 5 with 800 is Euler (800/5 = 160), ranging from 1 ~ In 800, the number of public appointments with 800 is 160 Euler (800/160 = 5.
Therefore, the total number in the 5*160 group is Erler (5) * Euler (160.
Then I encountered a problem. After finding out its prime factor, I didn't know how to find all the dikes, and then I didn't know how to do it. Then I found that it could be directly violent and SQRT (n) complexity. Time is acceptable.
Note that whether N is equal to 1. If n is equal to 1, 1 is output directly.
#include<stdio.h>#include<algorithm>#include<iostream>#include<vector>#include<string.h>#define LL long longusing namespace std;LL n,k;LL euler(LL x) { LL res = x; for (LL i = 2; i <= x / i; i++) if (x % i == 0) { res = res / i * (i - 1); while(x % i == 0) x /= i; } if (x > 1) res = res / x * (x - 1); return res;}const LL mod=1000000007;int main(){ while(scanf("%I64d%I64d",&n,&k)!=EOF) { if(n==1) {printf("1\n"); continue;} if(k>2) {printf("0\n"); continue;} if(k==2) {printf("1\n"); continue;} else { LL ans=0; for(LL i=1;i*i<=n;++i) { if(n%i==0) { LL x=n/i; if(i*i==n) ans+=euler(x)*euler(i); else ans+=euler(x)*euler(i)*2; ans%=mod; } } printf("%I64d\n",ans); } } return 0;}
I wanted to directly create a 1000000000/2 table and found that the table was too big to be typed ......
Later, let's look at the problem solution and find a map table used by a person. It's awesome to think about it. The time complexity is halved.
map<int,int> mp;int phi(int n){ int i,mul,nn; if (n==1) return 1; if (mp.find(n)!=mp.end()) return mp[n]; for (i=2;i*i<=n;i++) if (n%i==0) { nn=n; nn/=i; mul=(i-1); while (nn%i==0) { nn/=i; mul*=i; } mp[n]=phi(nn)*mul; return phi(nn)*mul; } mp[n]=n-1; return n-1;}
Note that there must be an operation in the main function:
mp.clear();
Gcd (n? A, n) × gcd (n? B, n) = NK .
Bestcode #6-1003 HDU 4983 goffi and GCD [Euler's function]