[ Codeforces Round #549 (Div. 2)][D. The Beatles][exgcd]
https://codeforces.com/contest/1143/problem/D
Recently a Golden Circle of Beetlovers was found in Byteland. It is a circle route going through n⋅kn⋅k cities. The cities are numerated from 11to n⋅kn⋅k, the distance between the neighboring cities is exactly 11 km.
Sergey does not like beetles, he loves burgers. Fortunately for him, there are nn fast food restaurants on the circle, they are located in the 11-st, the (k+1)(k+1)-st, the (2k+1)(2k+1)-st, and so on, the ((n−1)k+1)((n−1)k+1)-st cities, i.e. the distance between the neighboring cities with fast food restaurants is kk km.
Sergey began his journey at some city ss and traveled along the circle, making stops at cities each ll km (l>0l>0), until he stopped in ss once again. Sergey then forgot numbers ss and ll, but he remembers that the distance from the city ss to the nearest fast food restaurant was aakm, and the distance from the city he stopped at after traveling the first ll km from ss to the nearest fast food restaurant was bb km. Sergey always traveled in the same direction along the circle, but when he calculated distances to the restaurants, he considered both directions.
Now Sergey is interested in two integers. The first integer xx is the minimum number of stops (excluding the first) Sergey could have done before returning to ss. The second integer yy is the maximum number of stops (excluding the first) Sergey could have done before returning to ss.
The first line contains two integers nn and kk (1≤n,k≤1000001≤n,k≤100000) — the number of fast food restaurants on the circle and the distance between the neighboring restaurants, respectively.
The second line contains two integers aa and bb (0≤a,b≤k20≤a,b≤k2) — the distances to the nearest fast food restaurants from the initial city and from the city Sergey made the first stop at, respectively.
Print the two integers xx and yy.
2 3 1 1
1 6
3 2 0 0
1 3
1 10 5 3
In the first example the restaurants are located in the cities 11 and 44, the initial city ss could be 22, 33, 55, or 66. The next city Sergey stopped at could also be at cities 2,3,5,62,3,5,6. Let's loop through all possible combinations of these cities. If both ss and the city of the first stop are at the city 22 (for example, l=6l=6), then Sergey is at ss after the first stop already, so x=1x=1. In other pairs Sergey needs 1,2,31,2,3, or 66 stops to return to ss, so y=6y=6.
In the second example Sergey was at cities with fast food restaurant both initially and after the first stop, so ll is 22, 44, or 66. Thus x=1x=1, y=3y=3.
In the third example there is only one restaurant, so the possible locations of ss and the first stop are: (6,8)(6,8) and (6,4)(6,4). For the first option l=2l=2, for the second l=8l=8. In both cases Sergey needs x=y=5x=y=5 stops to go to ss.
题意:有一个总长度为n*K的环,每隔K有一个饭店,你的初始位置不知道,只知道你初始位置距离最近的饭店距离为 A,你每次移动L米然后停下来,但是L也未知,但是知道你第一次停下来距离你最近的饭店距离为B,你再次停在初始位置时结束旅行,求你可能的最大停留次数和最小停留次数
题解:由题意可得几个等式:等式一:ans*L=n*K*t,并且gcd(ans,t)==1,也就是你经过ans次之后停在了初始位置 等式二:L=(a+b)+t1*K 等式三:L=(-a-b)+t2*K 等式四:L=(a-b)+t3*K 等式五:L=(b-a)+t4*K 等式二~五是初始位置和第一次停留的可能情况,而等式一变形为L=n*K/ans * t,则可以分别和等式二~五联立,得到诸如 n*K/ans *t - K*t1 = (a+b)的式子,而ans必须有 n*k%ans==0,所以ans的个数就是n*k的因子数,n*k<=1e10,所以ans的个数很少,所以可以直接通过枚举n*K的因子ans再利用扩展欧几里德来求解t,并且判断 gcd(ans,t)是否=1即可
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdio> 6 #include<vector> 7 #include<queue> 8 using namespace std; 9 typedef long long ll; 10 ll gcd(ll x,ll y){ 11 if(y==0)return x; 12 return gcd(y,x%y); 13 } 14 ll qwq[100005],tot,qaq[100005],tot2; 15 16 ll exgcd(ll m, ll n, ll &x, ll &y) { 17 if (n == 0) { 18 x = 1; y = 0; 19 return m; 20 } 21 ll a, a1, b, b1, c, d, q, r, t; 22 a1 = b = 1; 23 a = b1 = 0; 24 c = m; d = n; 25 26 q = c/d; r = c%d; 27 while (r) { 28 c = d; 29 d = r; 30 t = a1; 31 a1 = a; 32 a = t - q * a; 33 t = b1; 34 b1 = b; 35 b = t - q * b; 36 q = c/d; 37 r = c%d; 38 } 39 x = a; y = b; 40 return d; 41 } 42 int main(){ 43 ll n,k,a,b; 44 scanf("%lld%lld%lld%lld",&n,&k,&a,&b); 45 ll ss=n*k; 46 for(ll i=1;i*i<=ss;i++){ 47 if(ss%i==0){ 48 qwq[++tot]=i; 49 if(ss!=i*i)qwq[++tot]=ss/i; 50 } 51 } 52 sort(qwq+1,qwq+1+tot); 53 for(int i=1;i<=tot;i++){ 54 if((a+b)%gcd(n*k/qwq[i],k)==0||(abs(a-b))%gcd(n*k/qwq[i],k)==0){ 55 printf("%lld ",qwq[i]); 56 break; 57 } 58 } 59 for(int i=tot;i>=1;i--){ 60 ll q1=gcd(n*k/qwq[i],k); 61 ll q2=gcd(n*k/qwq[i],k); 62 if(((a+b)%q1==0)||(abs(a-b))%q2==0){ 63 if(((a+b)%q1==0)){ 64 ll xx,yy; 65 exgcd(n*k/qwq[i],k,xx,yy); 66 xx*=(a+b)/q1; 67 while(xx>0&&k/q1)xx-=k/q1; 68 while(xx<=0&&k/q1)xx+=k/q1; 69 if(gcd(xx,qwq[i])==1){printf("%lld\n",qwq[i]);return 0;} 70 } 71 if((abs(a-b))%q2==0){ 72 ll xx,yy; 73 exgcd(n*k/qwq[i],k,xx,yy); 74 xx*=abs(a-b)/q2; 75 while(xx>0&&k/q2)xx-=k/q2; 76 while(xx<=0&&k/q2)xx+=k/q2; 77 if(gcd(xx,qwq[i])==1){printf("%lld\n",qwq[i]);return 0;} 78 } 79 if(((-a-b)%q1==0)){ 80 ll xx,yy; 81 exgcd(n*k/qwq[i],k,xx,yy); 82 xx*=(-a-b)/q1; 83 while(xx>0&&k/q1)xx-=k/q1; 84 while(xx<=0&&k/q1)xx+=k/q1; 85 if(gcd(xx,qwq[i])==1){printf("%lld\n",qwq[i]);return 0;} 86 } 87 if((-abs(a-b))%q2==0){ 88 ll xx,yy; 89 exgcd(n*k/qwq[i],k,xx,yy); 90 xx*=-abs(a-b)/q2; 91 while(xx>0&&k/q2)xx-=k/q2; 92 while(xx<=0&&k/q2)xx+=k/q2; 93 if(gcd(xx,qwq[i])==1){printf("%lld\n",qwq[i]);return 0;} 94 } 95 } 96 } 97 return 0; 98 }