首页 > 代码库 > CodeForces 492E Vanya and Field

CodeForces 492E Vanya and Field

题意:

n*n的矩形内有m(10^5)个点  从任一点开始以速度向量(dx,dy)移动  直到走到曾经走过的位置  问  从哪里开始  可以经过最多的点数  dx和dy均与n互素

思路:

很容易想到以dx,dy移动的话  走的一定是一个圈  不会是出现“蝌蚪形”然后循环  注意题意最后一句  而且每个x坐标一定只经过一次

那么对于m个点  我们可以求出它是(0,y)这个点可以到达的  求解方法就是用拓展欧几里德解下面方程

(x+dx*k)%mod=xi , (y+dy*k)%mod=yi 其中x=0 那么可以先解出k  把k带到二式解出y

最后统计对于每个(0,y)可以到达的点数就是答案

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<bitset>
using namespace std;
typedef long long LL;
#define N 2000010

int n, m, ans;
LL dx, dy, posy;
map<LL, int> cnt;

long long extend_gcd(long long a, long long b, long long &x, long long &y) {
    if (a == 0 && b == 0)
        return -1;
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long d = extend_gcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

int main() {
    cin >> n >> m >> dx >> dy;
    LL k, tmpk;
    extend_gcd(dx, n, k, tmpk);
    while (m--) {
        LL x, y;
        cin >> x >> y;
        if (x != 0) {
            tmpk = k * x % n * dy % n;
            if (tmpk <= y)
                y = y - tmpk;
            else
                y = y + n - tmpk;
        }
        y %= n;
        cnt[y]++;
        if (cnt[y] > ans) {
            ans = cnt[y];
            posy = y;
        }
    }
    cout << "0 " << posy << endl;
    return 0;
}


CodeForces 492E Vanya and Field