Solution - Codeforces 1166E The LCMs Must be Large

rizynvu發表於2024-11-03

看著合法不是很好判斷,不如先去想一些不合法的情況。

可以透過手玩之類知道,若存在 \(i\not = j, S_i \cap C_j = \varnothing\),那麼必然無解。
證明考慮令 \(x = \operatorname{lcm}_{k\in S_i}(a_k), y = \operatorname{lcm}_{k\in S_j}(a_k), z = \operatorname{lcm}_{k\not\in S_i, k\not\in S_j} (a_k)\),那麼就是要滿足 \(x > \operatorname{lcm}(y, z), y > \operatorname{lcm}(x, z)\),但是注意到 \(\operatorname{lcm}(x, z) \ge x, \operatorname{lcm}(y, z) \ge y\),所以無解。

那麼剩下就是兩兩都有交的情況了,感受一下會感覺大抵是有解的,然後如果直接猜這個結論就過了(。
但是還是需要個證明的,考慮到滿足的相當於是 \(\operatorname{lcm}_{j\in S_i}(a_j) > \operatorname{lcm}_{j\not \in S_i}(a_j)\),那麼一個想法是給 \(S_i\) 中的值賦一個與 \(i\) 有關的值。
並且考慮到 \(\operatorname{lcm}\)\(\gcd\) 的存在太特殊,不妨直接特化,欽定每一個跟 \(i\) 有關的值都是個質數(例如第 \(i\) 個質數 \(\operatorname{pr}_i\)),且直接特化 \(>\) 為成倍數關係。

考慮構造,那麼根據之前的想法,可以初始值都賦為 \(1\)
然後對於 \(j\in S_i\),令 \(a_j\leftarrow a_j\times \operatorname{pr}_i\)

考慮這為什麼是對的,首先是因為 \(\operatorname{lcm}_{j\in S_i}(a_j)\) 中一定含 \(\operatorname{pr}_i\),而 \(\operatorname{lcm}_{j\not \in S_i}(a_j)\) 不含。
同時對於 \(S_k(k\not = i)\),因為 \(S_i\cap S_k\not = \varnothing\),所以若 \(S_k\subseteq S_i\),那麼 \(\operatorname{pr}_k\) 只貢獻給了 \(\operatorname{lcm}_{j\in S_i}(a_j)\),否則兩部分都貢獻了,一定滿足條件。

時間複雜度 \(\mathcal{O}(\frac{nm^2}{\omega})\)

#include<bits/stdc++.h>
const int maxn = 1e4 + 10, maxm = 50 + 2;
std::bitset<maxn> b[maxm];
int main() {
   int n, m;
   scanf("%d%d", &m, &n);
   for (int i = 1, k; i <= m; i++) {
      scanf("%d", &k);
      for (int x; k--; ) {
         scanf("%d", &x), b[i].set(x);
      }
   }
   for (int i = 1; i <= m; i++) {
      for (int j = i + 1; j <= m; j++) {
         if ((b[i] & b[j]).none()) {
            return puts("impossible"), 0;
         }
      }
   }
   return puts("possible"), 0;
}

相關文章