ab题没啥好说的,b题一开始看题错成线段树了,后面发现维护最大值就过了(我就说b怎么会有线段树)。。。
C:Dora and C++
卡的我死死的,好久没卡c了,数论果然是最短板。。。我有两个推论,但是一个都不会用:
1.翡蜀定理。(但是这题只有正数)(处理两个数的情况)
2.断环为链。(但是我只会n方,即以每个点为起点,把其他点都排在他后面)(处理只有一个数的情况)
正解是这样:
-
确实是翡蜀定理,因为对\(a_i\)减去一个数相当于对其余数加上一个数
-
断环为链只需要把第一个节点放到最后去,并不需要重新维护整个链
把上述两个结论结合我们就可以用\(gcd(a,b)\)一个数去处理所有节点了,结束。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
int a[maxn];
signed main() {
int t; cin >> t;
while (t--) {
int n,x,y;
cin>>n>>x>>y;
x=__gcd(x,y);
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);
if(x==1){
cout<<0<<"\n";
continue;
}
for(int i=1;i<n;i++){
int tmp=(a[n]-a[i])/x;
a[i]+=tmp*x;
}
sort(a+1,a+n+1);
int mx=a[n];int ans=0x3f3f3f3f;
for(int i=1;i<=n;i++){
ans=min(ans,mx-a[i]);
mx=a[i]+x;
}
cout<<ans<<"\n";
}
}