什么?竟然是裴蜀定理。。。
由于这里给出了a和b两个数,我们或许可以想到使用同样是需要给出两个定值的裴蜀定理,即:
- 如果给定 x x x和 y y y,那么一定有 a x + b y = g c d ( x , y ) ax+by=gcd(x,y) ax+by=gcd(x,y)。
所以在这时候我们就可以让输入的所有数都去对 g c d ( a , b ) gcd(a,b) gcd(a,b)取模,这样就能够得到所有数的最简形式(可以当成是让所有数尽可能消去 a a a和 b b b的组成)。
至于这里为什么能减:
- 虽然这里给我们的条件是只能够加,但是一个数加了就相当于其他数都在减,所以我们可以直接将其转化为减操作。
那么在取模之后我们现在排序,得到的极差就是 c [ n ] − c [ 1 ] c[n] - c[1] c[n]−c[1],那么这里我们还要进行一次 o ( n ) o(n) o(n)的判断,因为不排除有这种情况存在 c [ i ] + g − c [ i − 1 ] < c [ n ] − c [ 1 ] c[i] + g - c[i-1] < c[n] - c[1] c[i]+g−c[i−1]<c[n]−c[1],这样我们会取到最优解。
void solve()
{
int n,a,b;cin >> n >> a >> b;
int g = __gcd(a,b);
vector<int>c(n);
for(int i = 0;i < n;i++){
cin >> c[i];
c[i]%=g;
}
sort(c.begin(),c.end());
int res = c[n-1] - c[0];
for(int i = 1;i < n;i++){
res = min(res,c[i] + g - c[i-1]);
}
cout << res << endl;
}