一.G - Yet Another mod M (atcoder.jp)
(1)题目大意
给定你n个数,让你求一个模数m,使得所有数模上m后,出现了绝对众数(指这个数在原序列中出现的次数>n/2)。

(2)解题思路
对于一个区间的绝对众数,我们可以采取摩尔投票法消除,最后出现的一定是绝对众数,或者不存在绝对众数。而对于这个题目我们的目标是模上m后的绝对总数,假定x和y都是绝对众数,那么又(x - y) % m = 0,我们随即化选择k次,那么正确率为1-(3/4)^k,那么m肯定是x-y的因子,然后判断一下是否符合原序列条件即可。
(3)代码实现
#include "bits/stdc++.h"
using namespace std;
const int N = 5010;
int a[N],n;
void check(int x)
{
if(x < 3) return ;
map <int,int> mp;
for(int i = 1;i <= n;i++) {
if(++mp[a[i] % x] > n / 2){
cout << x << endl;
exit(0);
}
}
}
void solve()
{
int s = 0,t = 0;
while(s == t) s = rand() % n,t = rand() % n;
s ++,t ++;
int val = abs(a[s] - a[t]);
for(int i = 1;i <= val / i;i++)
if(val % i == 0)
check(i),check(val / i);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n;
for(int i = 1;i <= n;i++) cin >> a[i];
srand(time(0));
int T = 50;
while(T --) solve();
cout << -1 << endl;
return 0;
}

本文介绍了一种求解绝对众数的算法,通过摩尔投票法和随机化技巧找到一组数经模运算后可能出现的绝对众数。利用数学性质缩小候选模数范围,并通过代码实现验证解的有效性。
2098

被折叠的 条评论
为什么被折叠?



