CF763C Timofey and Remoduling


題目戳這里

這道題目純粹是考思維。
\(2N \le M\),由於答案肯定是\(s,s+d,\dots,s+(N-1)d\),我們任意枚舉兩個數\(a,b\),不妨設\(b\)在數列中出現在\(a\)后面\(k\)位,設\(g = b-a\),則\(g\)這個差在所有數出現剛好\(N-K\)次。我們任取個\(g\),用二分或哈希求個差出現次數,就可以得知\(k\)了,然后\(d = gk^{-1}\)。在檢驗數列中有\(a\)的公差為\(d\)的等差數列是否存在即可。

\(2N > M\),我們考慮這些數的補集即可,這樣就可以求出\(d\)了。

然后為什么\(2N > M\)不能用第一種情況來做呢?因為\(kd\)這個差不一定出現\(N-k\)次。因為假設我枚舉到的差是\((N-1)d\),那么\(s+(2N-2)d\)這個數有可能在模\(M\)意義下是在數列中的,但是這個數字又是不合法的。

程序實現還有一些細節,可以參考一下代碼。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
using namespace std;

typedef long long ll;
const int maxn = 100010;
int M,N,A[maxn],B[maxn],ans1,ans2;

inline int gi()
{
	char ch; int ret = 0,f = 1;
	do ch = getchar(); while (!(ch >= '0'&&ch <= '9')&&ch != '-');
	if (ch == '-') f = -1,ch = getchar();
	do ret = ret*10+ch-'0',ch = getchar(); while (ch >= '0'&&ch <= '9');
	return ret*f;
}

inline ll qsm(ll a,int b)
{
	ll ret = 1;
	for (;b;b >>= 1,(a *= a) %= M) if (b&1) (ret *= a) %= M;
	return ret;
}

inline bool find(int *a,int n,int x) { return a[lower_bound(a+1,a+n+1,x)-a] == x; }

inline void solve(int *a,int n)
{
	if (n == 1) { ans1 = a[1],ans2 = 1; return; }
	int tmp = a[2]-a[1],cnt = 0,tot = 1;
	for (int i = 1;i <= n;++i) cnt += find(a,n,(a[i]+tmp)%M);
	ans2 = qsm(n-cnt,M-2)*tmp%M;
	for (int now = a[1],nx;;now = nx,++tot)
	{
		nx = now+ans2; if (nx >= M) nx -= M;
		if (!find(a,n,nx)) break;
	}
	for (int now = a[1],nx;;now = nx,++tot)
	{
		ans1 = now; nx = now-ans2; if (nx < 0) nx += M;
		if (!find(a,n,nx)) break;
	}
	if (tot != n) ans1 = -1; 
}

int main()
{
	freopen("763C.in","r",stdin);
	freopen("763C.out","w",stdout);
	M = gi(); N = gi();
	for (int i = 1;i <= N;++i) A[i] = gi();
	sort(A+1,A+N+1);
	if (N == 1||N == M) printf("%d 1\n",A[1]);
	else
	{
		if (2*N <= M) solve(A,N);
		else
		{
			int n = 0;
			for (int i = 0;i < M;++i) if (!find(A,N,i)) B[++n] = i;
			solve(B,n);
			if (ans1 != -1) { ans1 += (ll)n*ans2%M; if (ans1 >= M) ans1 -= M; }
		}
		if (ans1 == -1) puts("-1");
		else printf("%d %d\n",ans1,ans2);
	}
	fclose(stdin); fclose(stdout);
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM