Solution - Luogu P9575 「TAOI-2」喵了個喵 Ⅳ

rizynvu發表於2024-10-25

首先對於 \(n\bmod 2 = 0\) 的情況,比較顯然的是直接令 \(x = 1\)
這樣就有 \(\gcd(a_i, x) = 1\) 了,那麼直接每部分 \(\frac{n}{2}\) 個即可。

接下來考慮 \(n\bmod 2 = 1\) 的情況。
此時就發現 \(x = 1\) 不管用了,因為此時 \(\sum \gcd(a_i, x) = n \bmod 2 = 1\)

注意到部分分中有個 \(a_i\bmod 2 = 1\) 的 sub。
如果去手玩一下能夠發現這必定無解。

思考一下這是為什麼,考慮找一下合法的必要條件。
注意到因為 \(\sum_{y\in B} \gcd(x, y) = \sum_{y\in C} \gcd(x, y)\),那麼必然有 \(\sum\limits \gcd(a_i, x)\bmod 2 = 0\) 才有可能有合法的拆分。

那麼對於 \(a_i\bmod 2 = 1\),能夠發現無論如何選擇 \(x\) 都有 \(\gcd(a_i, x)\bmod 2 = 1\),所以最後的總和必定還是 \(\bmod\ 2 = 1\)

於是現在的一個想法是首先調整總和為偶數,再進一步考慮。
那麼考慮如何調整總和為偶數,因為當 \(x = 1\)\(\gcd(a_i, x) = 1\),那麼就可以透過將 \(\gcd(a_i, x)\) 變為偶數的方式使得奇偶性變換。
於是可以知道的是最後肯定有 \(2 | x\)

同時發現繼續往 \(x\) 上乘一些數就不再會改變奇偶了,因為偶數依然為偶數,奇數依然為奇數。

所以只需要把 \(x = 2\) 先代入進去檢驗 \(\sum \gcd(a_i, x)\) 是否為偶數,如果為奇數則必然不可行。

然後考慮此時能不能構造了,發現因為此時 \(\gcd\) 只有 \(1, 2\),所以看起來已經能夠湊出來 \(\frac{\sum\limits \gcd(a_i, x)}{2}\) 了……嗎?

考慮到如果對於任意 \(i\),都有 \(\gcd(a_i, x) = 2\),那麼就構造不出來了。
但是注意到這等價於 \(\gcd(a_i, x) = 1\) 的情況,又可以繼續除掉這個 \(2\) 繼續處理了。

於是只需要得到 \(g = \gcd(a_1, \cdots, a_n)\),以 \(\frac{a_i}{g}\) 去處理就行了(此時至少有一個奇數),同時最後的 \(x\) 乘上 \(g\) 即可。

\(\gcd\) 的複雜度是均攤的,時間複雜度 \(\mathcal{O}(n + \log V)\)

#include<bits/stdc++.h>
const int maxn = 1e5 + 10;
int n, a[maxn], col[maxn];
int main() {
   scanf("%d", &n);
   if (~ n & 1) {
      puts("1");
      for (int i = 1; i <= n; i++) {
         putchar((i <= n / 2) ^ '0');
      }
      return puts(""), 0;
   }
   for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
   int g = 0;
   for (int i = 1; i <= n; i++) g = std::__gcd(g, a[i]);
   int sum = 0;
   for (int i = 1; i <= n; i++) {
      a[i] /= g;
      a[i] = 1 + (~ a[i] & 1), sum += a[i];
   }
   if (sum & 1) {
      return puts("-1"), 0;
   }
   sum /= 2;
   for (int i = 1; i <= n; i++) {
      if (a[i] == 2 && sum >= 2) {
         col[i] = 1, sum -= 2;
      }
   }
   for (int i = 1; i <= n; i++) {
      if (! col[i] && sum >= a[i]) {
         col[i] = 1, sum -= a[i];
      }
   }
   printf("%d\n", g * 2);
   for (int i = 1; i <= n; i++) {
      printf("%d", col[i]);
   }
   return puts(""), 0;
}

相關文章