首页 > 其他分享 >AtCoder Beginner Contest 272 G - Yet Another mod M // 随机化

AtCoder Beginner Contest 272 G - Yet Another mod M // 随机化

时间:2022-10-13 00:44:49浏览次数:78  
标签:AtCoder cnt le Beginner int 随机化 众数 omega mod

题目来源:AtCoder Beginner Contest 272 G - Yet Another mod M

题目链接:ABC272 G - Yet Another mod M


题意

给定一个大小为\(N\),元素各不相同的数组\(A\)。

求一个数字\(M\),满足:\(3 \le M \le 10^9\),令\(A_1 := A_1\ mod\ M,\ A_2 := A_2\ mod\ M,\ ...,\ A_n := A_n\ mod\ M\),新数组\(A\)中存在绝对众数\(x\),使得等于\(x\)的元素个数严格大于不等于\(x\)的元素个数;若不存在,输出\(-1\)。

数据范围:\(3 \le N \le 5000\),\(1 \le A_i \le 10^9\).

思路:随机化

对于数组中两个元素\(x\)、\(y\),若他们均为众数,则有:\(x\ mod\ M \equiv y\ mod\ M \Leftrightarrow (x - y)\ mod\ M \equiv 0\)。即有,\(M\)为\(|x-y|\)的因子。

考虑从数组中随机取两个元素,若存在满足条件的\(M\),则取到两个众数的概率为\(\large \frac{1}{4}\),在第 \(k\) 次才取到均为众数的两个元素的概率为\(1 - \large (\frac{3}{4})^k\)。因此,随机地取个几十次,肯定能取到两个均为众数的元素,若还取不到,应该就是不存在这样的\(M\)。

于是每次随机取两个元素后,枚举他们的因子作为\(M\),判断下是否能满足条件。若满足条件则输出答案,结束循环;否则在循环一定次数后,输出\(-1\)表示无解。

记循环次数为\(\omega\),枚举的因数总个数为\(cnt\),则时间复杂度:\(O(\omega·\sqrt{A_i} + cnt·N)\).

\(\omega\)的大小取\(100\)已经足够大了,\([1,10^9]\)范围内的数,约数个数最多为\(1344\),因此\(cnt < \omega·1344\),这样极限复杂度为\(O(\omega·(\sqrt{A_i}+1344N))\),大概\(6.75·10^8\),但实际上的复杂度肯定还要更小。

代码

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

const int N = 5010;

int n, a[N];

bool check(int M, int rem)
{
	if(M < 3) return false;

	int cnt = 0;
	for(int i = 1; i <= n; i++) {
		if(a[i] % M == rem) ++ cnt;
	}
	return cnt >= n / 2 + 1;
}

int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);

	cin >> n;
	for(int i = 1; i <= n; i++) cin >> a[i];

	for(int cnt = 1; cnt <= 100; cnt++) {
		int x = a[rand() % n + 1], y = a[rand() % n + 1];
		int d = abs(x - y);
		for(int i = 1; i <= d / i; i++) {
			if(d % i) continue;
			int M = i;
			if(check(M, x % M)) {
				cout << M << endl;
				//for(int j = 1; j <= n; j++) cout << a[j] % M << " ";
				return 0;
			}
			M = d / i;
			if(check(M, x % M)) {
				cout << M << endl;
				//for(int j = 1; j <= n; j++) cout << a[j] % M << " ";
				return 0;
			}
		}
	}
	cout << -1 << endl;

	return 0;
}

标签:AtCoder,cnt,le,Beginner,int,随机化,众数,omega,mod
From: https://www.cnblogs.com/jakon/p/16786638.html

相关文章

  • AtCoder Regular Contest 150 (ARC150) - A+B+C+D 题解
    A题意给定一个由0,1和?组成的长为\(n\)序列,其中?需要被替换为0或1,询问是否有且仅有一种?的替换方案使得序列中有\(k\)个1并且这\(k\)个1是连续的序......
  • AtCoder Beginner Contest 272(A~E)
    Avoidsolve(intCase){intn;cin>>n;vector<int>a(n);for(auto&i:a)cin>>i;cout<<accumulate(all(a),0)<<nline;}Bconst......
  • 虫逢——随机化数据的随机化处理
    【清华集训2014】虫逢一道随机化数据的好题。题干小强和阿米巴是好朋友。阿米巴告诉小强,变形虫(又叫阿米巴虫)和绝大多数生物一样,也是有DNA的。并且,变形虫可以通过分......
  • AtCoder Beginner Contest 272 D Root M Leaper
    RootMLeaper\(bfs\)模拟先把能走的矩阵预处理出来,然后直接跑\(bfs\)要注意各种边界#include<iostream>#include<cstdio>#include<array>#include<queue>us......
  • AtCoder Beginner Contest 271
    咕咕咕咕。E-SubsequencePath最短路问题变种,Dijkstra最短路改改就行了。AC代码//Problem:E-SubsequencePath//Contest:AtCoder-KYOCERAProgrammingC......
  • AtCoder Regular Contest 149
    ARC149A-RepdigitNumber符合条件的数一共只有\(9N\)个,随便怎么做都行。ACCodeARC149B-TwoLISSum这个操作相当于我们可以将\(A\)任意排列,然后对\(B\)进行......
  • AtCoder Regular Contest 149(持续更新)
    Preface最近国庆在外面玩的有点high啊,欠了一篇AT和两篇CF没写,今天先浅浅写一下这场当时10.2号在外面玩得有点晚了,到寝室刚好比赛开始,晚饭都没吃就开干了主要是C写的太久......
  • AtCoder Regular Contest 149
    A发现所有数字都相同的数一共只有\(10^6\)种,考虑枚举每种情况,关键在于如何判断一个数\(\bmodm\)是否为\(0\)。考虑\(9\bmod8=1\),而\(99\bmod8=(9\times10+9)\b......
  • AtCoder Beginner Contest 271
    AtCoderBeginnerContest271D-FlipandAdjust一共有\(N\)张牌,每一面都写着一个整数。卡\(i(1\lei\leN)\)前面写着整数\(a_i\),后面写着整数\(b_i\)。你可......
  • AtCoder Regular Contest 137 D
    一道很好的题目,运用了很多不同的技巧。结论1:枚举变换次数\(k\),若\(A_{i}\)对答案有贡献,当且仅当\(C_{n-i+k-1}^{k-1}\equiv1\mod2\)。首先我们可以统计\(A_{p}\)对......