首页 > 技术文章 > codeforces 492E. Vanya and Field(exgcd求逆元)

littlepear 2016-08-14 22:49 原文

题目链接: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\n",mmm);
55     return 0;
56 }

 

推荐阅读