Codeforces into C Prefix Product Sequence (Modulo inverse element + constructor), codeforces487c

Source: Internet
Author: User
Tags modulus

Codeforces into C Prefix Product Sequence (Modulo inverse element + constructor), codeforces487c


C. Prefix Product Sequencetime limit per test1 secondmemory limit per test256 megabytes

Consider a sequence [A1, bytes,A2, middle..., middle ,...,AN]. Define its prefix product sequence.

Now givenN, Find a permutation of [1, interval 2, interval..., interval ,...,N], Such that its prefix product sequence is a permutation of [0, limit 1, limit..., limit ,...,NAccept-limit 1].

Input

The only input line contains an integerN(1 digit ≤ DigitNLimit ≤ limit 105 ).

Output

In the first output line, print "YES" if such sequence exists, or print "NO" if no such sequence exists.

If any solution exists, you should outputNMore lines.I-Th line contains only an integerAI. The elements of the sequence shocould be different positive integers no largerN.

If there are multiple solutions, you are allowed to print any of them.

Sample test (s) Input
7
Output
YES1436527
Input
6
Output
NO
Note

For the second sample, there are no valid sequences.


Link: http://codeforces.com/problemset/problem/487/C


Construct a 1 ~ The arrangement of n makes the n prefix product a 0-to-n remainder ~ N-1 Arrangement


Question Analysis: first, we can use a simple analysis to obtain that n is definitely the last number, because if n is in front, more than one prefix product must be a multiple of n, that is to say, there must be at least two zeros for n modulo operations, which obviously does not satisfy the arrangement. That is to say, the last number in the modulo operation is 0, and the first n-1 number is considered, if it is 1 2 3 4... is n-1 satisfying the condition? Obviously, the first number makes it 1, which is always correct. We have constructed two numbers and then let's look at them, for a group of sequences a1 a2 a3 a4... an-1, a1 = 1. If a2 needs to prefix the product of n after the modulo is obtained, and a1 * a2 * a3 has different modulo values for n than a1 * a2, we may wish to eliminate the influence of a2 on prefix products in a3, and so on. In this case, we will use the concept of mod-inverse element.

For positive integers and, if any, the minimum positive integers in the same equation are called the inverse element of the modulus. If it is a prime number, you can also obtain the inverse element according to the Fermat theorem. The derivation is as follows:

Back to this question, we can construct ai = (I + 1) * inv [I], (inv [I] indicates the module inverse of I)

Prefix a1a2a3... an-1 = 1*2 * inv [1] * 3 * inv [2] *... * n * inv [n-1] Because inv [2] * 2 limit 1 (mod n) is equivalent to eliminating the influence of a2 on a3. If n is the sum, it must be expressed as x * y. Here, x and y are other factors except 1 and n. Therefore, for prefix products (n-1 )! It is bound to be divisible by n. Here is a special case, 4, which can be constructed as 1, 3, 2, 4. The reason is very simple, because 4 is not counted as the prefix product of the last item is 2*3 obviously 6 cannot be divisible by 4, but the smallest sum of 4 is 6, 6 is not satisfied, because 5! = 2*3*4*5 is obviously a multiple of 6. When n expands, more and more factors are able to be divisible by n, therefore, we can't construct such a sequence for all the operators except 4. The next question is how to calculate the modulus inverse element.

According to the above conclusion, we can use the ferma's small theorem to solve the modulo inverse element through a rapid power modulo. However, there is a simpler recursive formula.

Inv [I] = (n-n/I) * inv [n % I] % n. THE RECURSIVE FORMULA OF inv [1] = 1 is derived as follows:

A = n/I

B = n % I =>

A * I + B Limit 0 (mod n) (the entire division part + the remainder part is equal to n) =>

-A * I partition B (mod n) (the two sides except B * I) =>

-A * inv [B] ≡ inv [I] (mod n) (replace a and B) =>

-(N/I) * inv [n % I] ≡ inv [I] (mod n) (change the number on the left to a value greater than 0 and add n directly, because nmodn = 0) =>

(N-n/I) * inv [n % I] ≡ inv [I] (mod n) =>

Inv [I] = (n-n/I) * inv [n % I] % n

The following two solutions are provided:

1. Recurrence:

#include <cstdio>#include <cmath>#define ll long longint const MAX = 1e5 + 10;ll inv[MAX];int n;bool isprime(int x){    if(x == 1)        return false;    if(x == 2)        return true;    if(x % 2 == 0)        return false;    for(int i = 3; i <= sqrt(n); i += 2)         if(n % i == 0)             return false;    return true;}int main() {    scanf("%d", &n);    if(n == 4)     {          printf("YES\n1\n3\n2\n4\n");          return 0;      }      else if(n == 1)    {        printf("YES\n1\n");        return 0;    }    else if(!isprime(n))    {        printf("NO\n");        return 0;    }    printf("YES\n1\n");    inv[1] = 1;    for(int i = 2; i < n; i++)     {        inv[i] = (n - n / i) * inv[n % i] % n;        printf("%lld\n", ((ll) i * inv[i - 1] % n));    }    printf("%d\n", n);}


2. ferma's small theorem + Rapid power modulo (20 times faster than 1st solutions)

#include <cstdio>#include <cmath>#define ll long longint const MAX = 1e5 + 10;ll inv[MAX];int n;bool isprime(int x){    if(x == 1)        return false;    if(x == 2)        return true;    if(x % 2 == 0)        return false;    for(int i = 3; i <= sqrt(n); i += 2)         if(n % i == 0)             return false;    return true;}ll multi(ll a, ll b)  {      ll ans = 0;      a %= n;      while(b)      {          if(b & 1)          {              ans = (ans + a) % n;              b--;          }          b >>= 1;          a = (a + a) % n;      }      return ans;  } ll quick_mod(ll a, ll b)  {      ll ans = 1;      a %= n;      while(b)      {          if(b & 1)          {              ans = multi(ans,a);              b--;          }          b >>= 1;          a = multi(a,a);      }      return ans;  }  int main() {    scanf("%d", &n);    if(n == 4)     {          printf("YES\n1\n3\n2\n4\n");          return 0;      }      else if(n == 1)    {        printf("YES\n1\n");        return 0;    }    else if(!isprime(n))    {        printf("NO\n");        return 0;    }    printf("YES\n1\n");    for(int i = 2; i < n; i++)         printf("%lld\n", i * quick_mod(i - 1, n - 2) % n);    printf("%d\n", n);}

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.