Codeforces problem plane portal & Luogu problem plane portal
A real educational hot tea.
First, let's see the preliminary transformation of the problem: we first find \ (\ prod \ limits {I = 1} ^ n (I!) \) In the prime factor decomposition form of, all prime numbers with odd occurrences are extremely easy to handle - because \ (\ prod \ limits {I = 1} ^ n (I!)= \prod\limits_{i=1}^ni ^ {n-i + 1} \), so the times of \ (n-1,n-3,\cdots,n\bmod 2+1 \) in the formula are even, and we can kick them out. Therefore, in the \ (\ prod \ limits {I = 1} ^ Ni! \) prime factor decomposition form, the set of prime factors with odd occurrences is equal to the set of prime factors with odd occurrences in \ (n!! \), After preprocessing the minimum prime factor of each number, it can be decomposed \ (n\log n \).
So the problem is to find a sequence with the smallest length \ (\ {a_m \} \), which satisfies \ (1\le a_i\le n \), and in the prime factor decomposition form of \ (\ prod \ limits {I = 1} ^ ma_i! \), the set of prime factors with odd occurrences is equal to the set of prime factors with odd occurrences of \ (n!! \). Here, we might as well discover the following properties: if \ (n \) is an even number, then \ (n!!=2^{n/2} · (\ dfrac{n}{2})! \), The former module of prime number \ (2 \) is followed by either \ (2 ^ 0 \) or \ (2 ^ 1 \), so the set with \ (n!! \) prime factor of odd number is either the same as \ (\ dfrac{n}{2})! \) Same as \ (2 · (\ dfrac{n}{2})! \) Same; Similarly, if \ (n \) is an odd number, then \ (n!!=\dfrac{n!}{(n-1)!!}=\dfrac{n!}{2^{(n-1)/2}·(\frac{n-1}{2})!}\), Therefore, for odd numbers \ (n \), \ (n!! \) sets with odd occurrences are either the same as \ (n! · (\ dfrac{n-1}{2})! \) Same as \ (2 · n! · (\ dfrac{n-1}{2})! \) Same.
That is, the length of the sequence \ ({a_m} \) with the smallest length that meets the condition shall not exceed \ (3 \). Therefore, we consider solving the cases of \ (0,1,2 \) separately. We can directly judge the case of \ (0 \), and consider hashing for the case of \ (1 \). We assign a random weight of \ ([1,2 ^ {64}-1] \) to each quality factor, and then define the weight of a set as the XOR of the weight of all elements in it. In this way, after preprocessing the weight of \ (1!,2!,\cdots,n! \), Check whether the weight of a \ (i! \) is equal to the weight of \ (n!! \). The same is true for \ (2 \). The position of each weight in map preprocessing can be used.
Time complexity \ (n\log n \).
mt19937 rng(20060729 ^ chrono :: steady_clock :: now().time_since_epoch().count()); template<typename T> T rand(T l, T r) {return uniform_int_distribution<T>(l, r)(rng);} const int MAXN = 1e6; int n, pr[MAXN / 2 + 5], prcnt = 0, vis[MAXN + 5], mnp[MAXN + 5]; int cnt[MAXN + 5], book[MAXN + 5]; u64 v[MAXN + 5], pre[MAXN + 5]; void sieve(int n) { for (int i = 2; i <= n; i++) { if (!vis[i]) pr[++prcnt] = i, mnp[i] = i; for (int j = 1; j <= prcnt && pr[j] * i <= n; j++) { vis[pr[j] * i] = 1; mnp[pr[j] * i] = pr[j]; if (i % pr[j] == 0) break; } } } int main() { scanf("%d", &n); sieve(MAXN); for (int i = 1; i <= n; i++) if ((n - i + 1) & 1) { int tmp = i; while (tmp ^ 1) { int p = mnp[tmp]; while (tmp % p == 0) tmp /= p, cnt[p] ^= 1; } } bool flg = 1; for (int i = 1; i <= n; i++) flg &= (!cnt[i]); if (flg) { printf("%d\n", n); for (int i = 1; i <= n; i++) printf("%d%c", i, " \n"[i == n]); return 0; } for (int i = 1; i <= n; i++) v[i] = rand(1ull, ULLONG_MAX); u64 hs = 0; for (int i = 1; i <= n; i++) if (cnt[i]) hs ^= v[i]; for (int i = 1; i <= n; i++) { pre[i] = pre[i - 1]; int tmp = i; while (tmp ^ 1) { int p = mnp[tmp]; while (tmp % p == 0) tmp /= p, pre[i] ^= v[p]; } } for (int i = 1; i <= n; i++) if (pre[i] == hs) { printf("%d\n", n - 1); for (int j = 1; j <= n; j++) if (j != i) printf("%d ", j); return 0; } unordered_map<u64, int> pos; for (int i = 1; i <= n; i++) { if (pos[pre[i] ^ hs]) { int X = i, Y = pos[pre[i] ^ hs]; printf("%d\n", n - 2); for (int i = 1; i <= n; i++) if (i != X && i != Y) printf("%d ", i); return 0; } pos[pre[i]] = i; } printf("%d\n", n - 3); for (int i = 1; i <= n; i++) if (i != 2 && i != (n >> 1) && i != n) printf("%d ", i); return 0; }