Math MagicTime
limit:3000MS
Memory Limit:32768KB
64bit IO Format:%lld &%llu< /c8> SubmitStatus
Description
Yesterday, my teacher taught us about math: +,-, *,/, GCD, LCM ... As you know, LCM (Least Common multiple) of the positive numbers can be solved easily because of a * b = GCD (A, b) * LCM (A, B).
In class, I raised a new idea: "How to calculate the LCM of K numbers". It's also an easy problem indeed, which only cost me 1 minute to solve it. I raised my hand and told teacher about my outstanding algorithm. Teacher just smiled and smiled ...
After class, my teacher gave me a new problem and he wanted me solve it in 1 minute, too. If We know three parameters N, M, K, and both equations:
1. SUM (A1, A2, ..., Ai, ai+1,..., AK) = N
2. LCM (A1, A2, ..., Ai, ai+1,..., AK) = M
Can calculate how many kinds of solutions is there for AI (AI is all positive numbers). I began to roll cold sweat but teacher just smiled and smiled.
Can you solve this problem in 1 minute?
Input
There is multiple test cases.
Each test case contains three integers N, M, K. (1≤n, m≤1,000, 1≤k≤100)
Output
For each test case, output an integer indicating the number of solution modulo 1,000,000,007 (1e9 + 7).
You can get more details in the sample and hint below.
Sample Input
4 2 23) 2 2
Sample Output
12
Hint
The first Test case:the only solution is (2, 2).
The second Test case:the solution is (1, 2) and (2, 1).
Test instructions: Give n,m,k, ask K number of and N, least common multiple for m case there are several ideas: because least common multiple is m, you can know that these numbers must be M factor, then we just need to select all of these factors, take these factors to the backpack can be dp[now][i][j] to indicate the current state, And for I, least common multiple is the number of solutions of J. Recursion k times out the answer. Attention needs optimization!!! See Code
#include <cstdio>#include<iostream>#include<cstring>using namespacestd;#defineMoD 1000000007intnum[ +];intdp[2][1010][1010];intlcm[1010][1010];intgcdintAintb//Greatest Common Divisor{ if(b==0)returnA; returnGCD (b,a%b);}intLcmintAintb//least common multiple{ return(a*b/gcd (A, b));}intMain () {intn,m,k; inti,j; for(i=1; i<= +; i++)//Pre -Treatment, the first 1000 least common multiple { for(j=1; j<= +; j + +) {Lcm[i][j]=LCM (I,J); } } while(SCANF ("%d%d%d", &n,&m,&k)! =EOF) { intCnt=0; //because least common multiple m is known, the AI must be his factor. for(i=1; i<=m;i++) { if(m%i==0) num[cnt++]=i; } //Dp[now][i][j]now represents the number of solutions for the current state, and for I, least common multiple J. Recursion k times out the answer. intnow=0; //memset (dp[nom],0,sizeof (dp[nom)); for(i=0; i<=n;i++) { for(j=0; j<cnt;j++) { //Initialize, and for I, least common multiple is num[j]dp[now][i][num[j]]=0; }} dp[0][0][1]=1; for(intt=1; t<=k;t++) { now^=1; for(i=0; i<=n;i++) { for(j=0; j<cnt;j++) {dp[now][i][num[j]]=0; } } for(i=t-1; i<=n;i++) { for(j=0; j<cnt;j++) { if(dp[now^1][i][num[j]]==0)Continue; for(intp=0;p <cnt;p++) { intx=i+Num[p]; inty=Lcm[num[j]][num[p]]; if(x>n| | m%y!=0)Continue; Dp[now][x][y]+=dp[now^1][i][num[j]]; Dp[now][x][y]%=MoD; } }}} printf ("%d\n", Dp[now][n][m]); } return 0;}
Math Magic (Full backpack)