D2. Half of Same(暴力&质因数分解)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D2. Half of Same(暴力&质因数分解)相关的知识,希望对你有一定的参考价值。
D2. Half of Same(暴力&质因数分解)
一开始想了一个假的做法,就是折半搜索,然后分别取gcd 再合并一下取个gcd 扫一遍取max。
显然可能某一组不需要所有数都相同,所有不能一组都取gcd。
正解:
枚举 a i a_i ai是要成为相同的那个数。
统计一下和 a i a_i ai相同的数: s a m e same same。
然后把所有大于 a i a_i ai的数和 a i a_i ai的差丢进一个数组: d . p u s h _ b a c k ( a j − a i ) d.push\\_back(a_j-a_i) d.push_back(aj−ai)。
对 d d d中所有数找到因数集合。用 m a p map map统计每个因数出现次数。
记录 c n t ≥ n 2 − s a m e cnt\\ge \\dfrac{n}{2}-same cnt≥2n−same 的因数取个 m a x max max即可。
时间复杂度: O ( n 2 m x ) O(n^2\\sqrt{mx}) O(n2mx)
#include <bits/stdc++.h>
using namespace std;
#define forn(i, n) for (int i = 0; i < int(n); i++)
set<int> divs(int n) {
set<int> d;
for (int dd = 1; dd * dd <= n; dd++)
if (n % dd == 0) {
d.insert(n / dd);
d.insert(dd);
}
return d;
}
int main() {
int t;
cin >> t;
forn(tt, t) {
int n;
cin >> n;
vector<int> a(n);
forn(i, n)
cin >> a[i];
int k = -1;
forn(i, n) {
int minv = a[i];
int same = 0;
vector<int> d;
forn(j, n) {
if (a[j] == minv)
same++;
else if (a[j] > minv)
d.push_back(a[j] - minv);
}
if (same >= n / 2) {
k = INT_MAX;
continue;
}
map<int,int> div_counts;
for (int di: d)
for (int dd: divs(di))
div_counts[dd]++;
for (auto p: div_counts)
if (p.second >= n / 2 - same)
k = max(k, p.first);
}
cout << (k == INT_MAX ? -1 : k) << endl;
}
}
以上是关于D2. Half of Same(暴力&质因数分解)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces1593 D2. Half of Same(随机)
Half Nice Years Gym - 101840H (点分治 or 并查集)
HDU 1592 Half of and a Half(大数)
John MayerTaylor Swift《Half Of My Heart》半颗心
[GeeksForGeeks] Remove all half nodes of a given binary tree