嘘~ 正在从服务器偷取页面 . . .

CF1322C Instant Noodles 题解


CF1322C Instant Noodles 题解

题目链接:CF1322C Instant Noodles

题意

\(t\)组测试数据。

给出一张点数为\(2N\)的二分图,其中右侧的第\(i\)个点有点权为\(c_i\)

\(S\)表示左侧点的一个非空点集,设\(f(S)\)表示右侧点中至少与\(S\)中一个点相连的点的点权和。

请你求出,对于所有非空集合\(S\)\(f(S)\)\(\gcd\)为多少。

\(1 \leq t,\sum n,\sum m \leq 5\times 10^5\)\(1 \leq c_i \leq 10^{12}\)

输入格式

The first line contains a single integer \(t\)(\(1 \leq t \leq 500\,000\)) — the number of test cases in the given test set. Test case descriptions follow.

The first line of each case description contains two integers \(n\) and \(m\) (\(1~\leq~n,~m~\leq~500\,000\)) — the number of vertices in either half of the graph, and the number of edges respectively.

The second line contains\(n\)integers \(c_i\)(\(1 \leq c_i \leq 10^{12}\)) . The\(i\)-th number describes the integer in the vertex\(i\)of the right half of the graph.

Each of the following\(m\)lines contains a pair of integers \(u_i\) and \(v_i\)(\(1 \leq u_i, v_i \leq n\)), describing an edge between the vertex \(u_i\) of the left half and the vertex \(v_i\) of the right half. It is guaranteed that the graph does not contain multiple edges.

Test case descriptions are separated with empty lines. The total value of\(n\)across all test cases does not exceed \(500\,000\) , and the total value of\(m\)across all test cases does not exceed \(500\,000\) as well.

输出格式

For each test case print a single integer — the required greatest common divisor.

众所周知,\(\gcd(a,b) = \gcd(a+b,b)\)

\(i,j\) 为右侧的两个点,\(S_i,S_j\) 为他们分别对应的左侧点集合。

  • \(S_i \cap S_j = \varnothing\) ,直接求 \(\gcd(c_i,c_j)\)

  • \(S_i = S_j\) ,则可以直接将 \(c_i,c_j\) 合并。

  • \(S_i \cap S_j \ne \varnothing\)

    对于这种情况,我们求的是 \(\gcd(c_i,c_i+c_j)\)\(\gcd(c_j,c_i+c_j)\)\(\gcd(c_i,c_j,c_i+c_j)\)

    结果发现这玩意好像就是 \(\gcd(c_i,c_j)\) 捏。

时间复杂度 \(\mathcal{O}(n \log c_i)\)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(5e5+15))

int n,m,c[N]; set<int> g[N]; map<set<int>, int> mp;
int gcd(int a,int b) { return b == 0 ? a : gcd(b, a%b); }
void work()
{
    mp.clear(); cin >> n >> m; int res = 0;
    for(int i=1; i<=n; i++){ cin >> c[i]; g[i].clear(); }
    for(int i=1,u,v; i<=m; i++) { cin >> u >> v; g[v].insert(u); }
    for(int i=1; i<=n; i++) if(!g[i].empty()) mp[g[i]] += c[i];
    for(auto i : mp) if(res) res = gcd(res, i.second); else res = i.second;
    cout << res << '\n';
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    int _Q = 1; cin >> _Q; while(_Q--) work();
    return 0;
}

参考文献

[1] https://www.luogu.com.cn/blog/jasony/cf1322c-instant-noodles


文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录