T2

场上打暴力直接拿到 15,各种胡乱优化后仍只有 20,出考场被同学告知去重就能 A,我那死去的脑细胞啊……

可恶的诈骗题。

有序列 \(a\),一共 \(n\) 个元素。有 \(q\) 次询问,对于每次询问 \(i\)\(1 \le i \le q\)),需要输出 \(a_1+i,a_2+i,\ldots,a_n+i\) 的最大公因数,即 \(\gcd (a_1+i,a_2+i,\ldots,a_n+i)\)。对于 \(k\) 个数,若 \(k \ge 3\)\(\gcd (c_1,c_2,\ldots,c_k)\) 就是 \(\gcd (\gcd(c_1,c_2,\ldots,c_{k-1}),c_k)\)

Part 1

我会暴力!

直接按题意模拟,先用一个数组 \(b\) 来存储,\(b_i\) 表示 \(a_i+i\) 的值。然后分两种情况,若 \(n \le 2\),直接输出 \(\gcd(b_1,b_2)\);从 \(1\) 遍历到 \(n-1\),用 \(ans\) 存当前的最大公因数,在 \(ans\)\(b_n\) 之间求最大公因数。

可拿 \(15\) 分,代码不放。

Part 2

我会优化!

首先,一旦 \(ans\) 变成 \(1\) 了,那就不用再看了,最大公因数必然为 \(1\),直接 break 掉,再加个特判。优化后可拿 \(17.5\) 分。

然后,注意到我存储 \(b_i\) 要从 \(1\)\(n\) 遍历,非常慢,不如直接在更新 \(ans\) 时先求 \(b_i\) 的值,在与 \(b_i\) 取最大公因数。优化后可拿 \(20\) 分。

于是这个蒟蒻觉得优化光了,开始推规律,结果一无所获,脑细胞全死光了……

呜呜呜,出了考场某大佬告诉我可以去重!对啊!

对于于所有测试点,保证 \(1 \le n \le 10^5\)\(1 \le q \le 10^5\)\(1 \le a_i \le 1000\)

因为有 \(n\)\(a_i\),既然 \(1 \le n \le 10^5\),但 \(a_i\) 的最大值 \(1000\)\(10^5\) 小,说明有重复的!

而且每次 \(a_i\) 加的 \(i\) 是相同的,所以 \(a_i\) 的顺序不重要,于是直接用 set 去重即可。

Code

#include <bits/stdc++.h>
#define qwq(i,a,b) for(int i=(a);i<=(b);++i)
#define qaq(i,a,b) for(int i=(a);i>=(b);--i)

using namespace std;

const int N = 1e5 + 5;

int n, q;
int b[N];

int ans;

int main()
{
	cin >> n >> q;
	
	set<int> st;
	qwq (i, 1, n) {
		int x;
		cin >> x;
		st.insert(x);
	}
	
	vector<int> a;
	for (auto it : st) {
		a.push_back(it);
	}
	
	int l = a.size();
	
	if (l <= 2) {
		qwq (i, 1, q) {
			b[1] = a[0] + i;
			b[2] = a[1] + i;
			
			cout << __gcd(b[1], b[2]) << '\n';
		}
	}
	
	qwq (i, 1, q) {
		bool f = 0;
		
		b[1] = a[0] + i;
		ans = b[1];
		
		qwq (j, 2, l - 1) {
			b[j] = a[j - 1] + i;
			ans = __gcd(ans, b[j]);
			
			if (ans == 1) {
				f = 1;
				break;
			}
		}
		
		if (f == 1) {
			cout << "1\n";
		} else {
			b[l] = a[l - 1] + i;
			ans = __gcd(ans, b[l]);
			cout << ans << '\n';
		}
	}
}
posted @ 2025-06-30 11:20  swate  阅读(11)  评论(0)    收藏  举报
body{ cursor: url(https://files.cnblogs.com/files/wkfvawl/cursor.ico),auto; }