CodeForces release C Prefix Product Sequence, codeforces487c
Question:
Construct a 1 ~ The arrangement of n makes n prefix product % n A 0 ~ N-1 Arrangement
Ideas:
First, confirm that n must be put. Otherwise, % n will have multiple zeros. Then, the prefix product at the n-1 position is (n-1 )!
Next we will discuss that when n is the Union number, only n = 4 has a solution, because if n is the Union number, it can be split into p * q in the form of obviously pq | (n-1 )!
Then construct ai = (I + 1) * inv [I] because (I + 1) * inv [I] = (j + 1) * inv [j] Must Have I = j. Therefore, this construction satisfies the need for ai to be unique, that is, an arrangement.
In addition, this structure makes the prefix a1 * a2 * a3... = 1*2 * inv [1] * 3 * inv [2]... then the result of % n is also an arrangement.
The final answer is 1 ~ The inverse element of n can be used as a table to find the recurrence formula (mod-mod/I) * inv [mod % I] % mod
PS: teammates said that the idea of construction comes from "this question % n must be very special, so try 1 2 3 4 5"
Code:
#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<map>#include<set>#include<vector>#include<queue>#include<cstdlib>#include<ctime>#include<cmath>using namespace std;typedef long long LL;#define N 100010int inv[N];int n;int main() { scanf("%d", &n); if (n == 1) { puts("YES"); printf("1\n"); return 0; } else if (n == 4) { puts("YES"); printf("1\n3\n2\n4\n"); return 0; } for (int i = 2; i * i <= n; i++) { if (n % i == 0) { puts("NO"); return 0; } } puts("YES"); puts("1"); inv[1] = 1; for (int i = 2; i < n; i++) { inv[i] = (LL) (n - n / i) * inv[n % i] % n; printf("%d\n", (int) ((LL) (i) * inv[i - 1] % n)); } printf("%d\n", n); return 0;}