Codeforces-1323E Instant Noodles
Codeforces-1323E Instant Noodles
Wu got hungry after an intense training session, and came to a nearby store to buy his favourite instant noodles. After Wu paid for his purchase, the cashier gave him an interesting task.
You are given a bipartite graph with positive integers in all vertices of the right half. For a subset \(S\) of vertices of the left half we define \(N(S)\) as the set of all vertices of the right half adjacent to at least one vertex in \(S\), and \(f(S)\) as the sum of all numbers in vertices of \(N(S)\). Find the greatest common divisor of \(f(S)\) for all possible non-empty subsets \(S\) (assume that GCD of empty set is \(0\)).
Wu is too tired after his training to solve this problem. Help him!
Input
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.
Output
For each test case print a single integer — the required greatest common divisor.
Example
Input
3
2 4
1 1
1 1
1 2
2 1
2 2
3 4
1 1 1
1 1
1 2
2 2
2 3
4 7
36 31 96 29
1 2
1 3
1 4
2 2
2 4
3 1
4 3
Output
2
1
12
Note
The greatest common divisor of a set of integers is the largest integer \(g\) such that all elements of the set are divisible by \(g\).
In the first sample case vertices of the left half and vertices of the right half are pairwise connected, and \(f(S)\) for any non-empty subset is \(2\), thus the greatest common divisor of these values if also equal to \(2\).
In the second sample case the subset \(\{1\}\) in the left half is connected to vertices \(\{1, 2\}\) of the right half, with the sum of numbers equal to \(2\), and the subset \(\{1, 2\}\) in the left half is connected to vertices \(\{1, 2, 3\}\) of the right half, with the sum of numbers equal to \(3\). Thus, \(f(\{1\}) = 2\), \(f(\{1, 2\}) = 3\), which means that the greatest common divisor of all values of \(f(S)\) is \(1\).
题意
给定一个二分图,每一个右半部分的点有一个点权,对于每一个左边的点集\(S\),有一个与之相连的右边的点集\(N(S)\),其点权和为\(f(S)\),问对于所有\(S\),\(f(S)\)的最大公约数为多少
题解
首先\(gcd(a,b)=gcd(a+b,b)\),所以我们只需要考虑那些没有交集最基本的右边集合即可.
我们要求的是所有\(f(S)\),所以我们考虑右边点的集合,对于一个右边的,其连向的左边的点集为\(S\),如果有两个右边的点连向的点集均为\(S\),则合并这两个点,因为他们必定同属于一个集合,对于所有不重复的右边基本集合均算出后做一遍gcd即可.
复杂度:对于每条边都会被扫一遍,记录对应的集合,加上排序,map处理映射,复杂度\(O(mlogm)\)
如何看右边的点连向的S是否相同,可以使用hash,在搜题解时发现了新的hash方法,一个是直接使用map映射vector,另一个是用异或.
- 使用map映射vector
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 50;
typedef long long ll;
ll c[N];
ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a % b);}
int main() {
int t; scanf("%d", &t);
while (t--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%lld", &c[i]);
vector<int> a[n + 1];
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
a[v].push_back(u);
}
for (int i = 1; i <= n; i++) {
if (a[i].size()) {
sort(a[i].begin(), a[i].end());
}
}
map<vector<int>, ll> mp;
for (int i = 1; i <= n; i++) {
if (!a[i].size()) continue;
if (!mp[a[i]]) {
mp[a[i]] = c[i];
}
else mp[a[i]] += c[i];
}
ll ans = 0;
for (auto e : mp) ans = gcd(ans, e.second);
printf("%lld\n", ans);
}
return 0;
}
//795ms
-
使用异或作为hash值
这里学习了https://blog.csdn.net/iamhpp/article/details/104826481的做法
就是给每个位置生成大随机数,然后将一个集合的异或起来,作为哈希值。
然后再用个哈希表把相同哈希值对应的 \(c_i\)加起来。
可以用 mt19937_64 生成大随机数
这个复杂度是最小的,接近 O(n)这样就不需要排序了,map的常数也变小了很多,注意mt19937返回值为unsigned
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 50;
typedef long long ll;
typedef unsigned long long ull;
ll c[N];
ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a % b);}
mt19937_64 rdn(time(0));
ull h[N];
ull rd[N];
int main() {
int t; scanf("%d", &t);
while (t--) {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
rd[i] = rdn();
h[i] = 0;
scanf("%lld", &c[i]);
}
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
h[v] ^= rd[u];
}
unordered_map<ull, ll> mp;
for (int i = 1; i <= n; i++) {
if (!h[i]) continue;
mp[h[i]] += c[i];
}
ll ans = 0;
for (auto e : mp) ans = gcd(ans, e.second);
printf("%lld\n", ans);
}
return 0;
}
//561ms
原文地址:https://www.cnblogs.com/artoriax/p/12575850.html
- 核心代码(未注释)
- 从科研角度谈“如何实现基于机器学习的智能运维”
- 用后台代码创建Storyboard
- 十分钟掌握微信小程序开发:高仿电商产品分类功能
- WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务
- DoubleAnimation方法
- 已经重写,源码和文章请跳转http://www.cnblogs.com/ymnets/p/5621706.html
- 有趣 不用js也能创建silverlight
- Hadoop和Spark的异同
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(62)-EF链接串加密
- sl 2.0 重要更新
- 云计算技术原理
- WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务
- 进入AI时代,你准备好了吗?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Web程序员的Mysql进阶序三之sql多表数据删除、子查询、联合查询
- nginx 修改配置文件使之支持pathinfo,且隐藏index.php
- 微信jssdk开发,PHP,必要步骤
- 微信JSSDK分享页面自定义当前链接最简单示例
- (一)python3 只需3小时带你轻松入门—— 编程尝试
- (二)python3 只需3小时带你轻松入门——基本变量
- (三)python3 只需3小时带你轻松入门—— 变量的简单运算
- (四)python3 只需3小时带你轻松入门—— 流程控制
- (五)python3 只需3小时带你轻松入门—— 逻辑运算符
- (六)python3 只需3小时带你轻松入门——循环
- (七)python3 只需3小时带你轻松入门——List与dict
- Rstudio支持可视化的Markdown编辑了?
- (八)python3 只需3小时带你轻松入门——List 与 dict 的常用操作
- (九)python3 只需3小时带你轻松入门——函数自定义
- (十)python3 只需3小时带你轻松入门——模块与包