cf492E. Vanya and Field(扩展欧几里得)
程序员文章站
2022-04-14 21:57:56
题意 $n \times n$的网格,有$m$个苹果树,选择一个点出发,每次增加一个偏移量$(dx, dy)$,最大化经过的苹果树的数量 Sol 上面那个互素一开始没看见,然后就GG了 很显然,若$n$和$dx$互素的话,每个$x$都能到达 我们预处理出在每个点$x = 0$时的$y$,取一下最大值 ......
题意
$n \times n$的网格,有$m$个苹果树,选择一个点出发,每次增加一个偏移量$(dx, dy)$,最大化经过的苹果树的数量
sol
上面那个互素一开始没看见,然后就gg了
很显然,若$n$和$dx$互素的话,每个$x$都能到达
我们预处理出在每个点$x = 0$时的$y$,取一下最大值即可
求解需要用到扩展欧几里得
/* */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<vector> #include<set> #include<queue> #include<cmath> //#include<ext/pb_ds/assoc_container.hpp> //#include<ext/pb_ds/hash_policy.hpp> #define pair pair<int, int> #define mp(x, y) make_pair(x, y) #define fi first #define se second #define int long long #define ll long long #define ull unsigned long long #define rg register #define pt(x) printf("%d ", x); //#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? eof : *p1++) //char buf[(1 << 22)], *p1 = buf, *p2 = buf; //char obuf[1<<24], *o = obuf; //void print(int x) {if(x > 9) print(x / 10); *o++ = x % 10 + '0';} //#define os *o++ = ' '; using namespace std; //using namespace __gnu_pbds; const int maxn = 1e6 + 10, inf = 1e9 + 10, mod = 1e9 + 7; const double eps = 1e-9; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int n, m, dx, dy, a, b; int num[maxn]; int exgcd(int a, int b, int &x, int &y) { if(!b) {x = 1; y = 0; return a;} int r = exgcd(b, a % b, x, y); int tmp = x; x = y; y = tmp - a / b * y; return r; } main() { n = read(); m = read(); dx = read(); dy = read(); int ans = 0; int x, y; for(int i = 1; i <= m; i++) { x = read(), y = read(); if(x == 0) {num[y]++; if(num[y] > num[ans]) ans = y;continue;} int r = exgcd(dx, n, a, b); a = (a + n) % mod; a = (a * x) % n; // a = y = (y - a * dy % n + n) % n; num[y]++; if(num[y] > num[ans]) ans = y; } printf("%d %d", 0, ans); return 0; } /* */