ACM Learning process-HDU 3092 Least Common multiple (number theory && dynamic planning && Large numbers)

Source: Internet
Author: User
Tags greatest common divisor

Hihocoder Challenge 12

Description

Partychen like to do mathematical problems. One day, when he is doing on a least common multiple (LCM) problem, he suddenly thought of a very interesting question:if Given a number of s, and we divided S into some numbers, then what is the largest LCM of these numbers? Partychen thought this problems for a long time and with no result, so he turned to your for help!
Since the answer can very big,you should give the answer modulo M.

Input

There is many groups of test case. On eachtest case only integers s (0 < S <=) and M (2<=m<=10000) as mentioned above.

Output

Output the largest LCM modulo M of given S.

Sample Input

6 23

Sample Output

6

Hint:you can divied 6 as 1+2+3 and THELCM (all in all) =6 is the largest so we output 6%23=6.

The main idea is to split a number into a number of numbers and then seek least common multiple for these several numbers. The maximum value of the least common multiple is obtained.

First, let's assume that for a number x, I've broken it into several numbers.

For each of the two numbers a and b. If these two numbers have greatest common divisor k.

Then these two least common multiple are a*b/k.

But if it is a and b/k, least common multiple is still a*b/k. But the two numbers and the smaller. So I can add a few more b-b/k, which may make the final result bigger.

So the first conclusion I've got is that I try to make sure that 22 counts are mutual.

Next, I want to prove that each number should be the form of p^t, p is prime.

Because when a > 1 &&b > 1 o'clock,

(A-1) (b-1) >= 1.

i.e. AB >= a+b.

In the same vein, get ABC >= ab+c>= a+b+c two times.

So, if a number y = p^t1*q^t2*c. P and q are prime numbers, and (p, q) = (p, c) = (q, c) = 1.

So I split it into P^t1 and Q^t2 and C, and the three-digit least common multiple is Y. But these three numbers and smaller, can add a number y-p^t-q^t-c, may make the result bigger.

So, the final conclusion x = 2^c1 + 3^c2 +5^c3 + ..., CI is prime.

There's a lot more to be done here.

One way to do this is to search directly with DFS violence.

Enumeration for a prime number p, plus p^i.

DFS (int now, int sum, BigInteger val)

Here now is the enumeration to the number of prime numbers, sum for the current situation, and Val for the current least common multiple.

So at the beginning of the introduction of S, to the second level of the recursive tree, respectively, 0, 2, 4,8 ...,

For a layer below 2 is 2, 2+3, 2+9 ...

First 3000 within the prime number of 430 or so. The number of layers may reach 430 levels, even if they are not full-branched, and the complexity is great.

Since then,

The P[i] array is then considered to represent the maximum value of the least common multiple of the I split.

Then p[i] = MAX (p[i-prime[k]^t] * prime[k]^t).

For I, enumeration is made up of i-prime[k]^t plus prime[k]^t. Then the maximum value is obtained so that the maximum value of the previously enumerated primes is memorized.

Complexity is: s*primenum*log (s), sum s* number of digits * Enumeration of the number of dimensions

Worst case scenario: 3000*430*log (3000) This complexity is not very large, so directly with the Java large number, the problem can be too, but the internet also has to take the logarithm to prevent data overflow method.

Code:

ImportJava.math.BigInteger;ImportJava.util.Scanner; Public classmain{BooleanIsprime[] =New Boolean[3005]; intPrime[] =New int[450]; inttop; BigInteger p[]=Newbiginteger[3005]; BooleanVis[] =New Boolean[3005]; //wagered sieve method for calculating primes    voidIsPrime () { for(inti = 0; i < 3005; ++i) isprime[i]=true; isprime[0] = isprime[1] =false;//Initialize         for(inti = 2; I <= 3000; ++i)//Sieve Method        {            if(Isprime[i]) { for(intj = i*i; J <= 3000; J + = i)//The upper bound is too large to explode int{Isprime[j]=false; }}} Top= 0;  for(inti = 0; I <= 3000; ++i)if(Isprime[i]) prime[top++] =i; } BigInteger DP (ints) {BigInteger ans=NewBigInteger ("1"); vis[0] =true;  for(inti = 1; I <= s; ++i) vis[i]=false; p[0] =NewBigInteger ("1");  for(inti = 0; I < top && prime[i] <= s; ++i) { for(intj = S; J >= Prime[i]; --j) { for(intk = Prime[i]; K <= J; K *=Prime[i]) {                    if(J-k < 0 | |!vis[j-K])Continue; if(!Vis[j]) {P[j]= P[j-k].multiply (NewBigInteger (integer.tostring (k))); VIS[J]=true; }                    ElseP[j]= P[j].max (P[j-k].multiply (NewBigInteger (integer.tostring (k))); }            }        }         for(inti = 1; I <= s; ++i)if(Vis[i]) ans=Ans.max (P[i]); returnans; }         Public Static voidMain (String args[]) {main QT=NewMain ();        Qt.isprime ();        BigInteger ans; intS, m; Scanner input=NewScanner (system.in);  while(Input.hasnext ()) {s=Input.nextint (); M=Input.nextint (); Ans=QT.DP (s); System.out.println (Ans.mod (NewBigInteger (Integer.tostring (m))); }    }}

ACM Learning process-HDU 3092 Least Common multiple (number theory && dynamic planning && Large numbers)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.