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";
}
}