题目链接:codeforces 492e vanya and field
留个扩展gcd求逆元的板子。
设i,j为每颗苹果树的位置,因为gcd(n,dx) = 1,gcd(n,dy) = 1,所以当走了n步后,x从0~n-1,y从0~n-1都访问过,但x,y不相同.
所以,x肯定要经过0点,所以我只需要求y点就可以了。
i,j为每颗苹果树的位置,设在经过了a步后,i到达了0,j到达了M.
则有
1----------------------(i + b * dx) % n = 0
2-----------------------(j + b * dy) % n = M % n
则2 * dx - 1 * dy消掉未知数 b.
得方程。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 typedef long long ll; 8 const ll mod = 1e9+7; 9 const int maxn = 1e6+5; 10 int vis[maxn]; 11 ll n,m,dx,dy; 12 ll ex_gcd(ll a,ll b, ll &x, ll &y) 13 { 14 if (b == 0) 15 { 16 x = 1; 17 y = 0; 18 return a; 19 } 20 else 21 { 22 ll gcd = ex_gcd(b, a % b, x, y); 23 ll t = x; 24 x = y; 25 y = t - (a / b) * y; 26 return gcd; 27 } 28 } 29 int main() 30 { 31 cin>>n>>m>>dx>>dy; 32 ll x,y; 33 ex_gcd(dx,n,x,y); 34 while(x<0) x+=n; 35 ll inv = x; 36 ll ans = 0; 37 ll i,j; 38 ll mm; 39 for(int k=0;k<m;k++) 40 { 41 scanf("%I64d %I64d",&i,&j); 42 mm = ((dx*j-dy*i)%n+n)%n*inv%n; 43 vis[mm]++; 44 } 45 ll mmm = 0; 46 for(int k=0;k<n;k++) 47 { 48 if(vis[k]>ans) 49 { 50 ans = vis[k]; 51 mmm = k; 52 } 53 } 54 printf("0 %I64d ",mmm); 55 return 0; 56 }