1. 程式人生 > >CF492E Vanya and Field

CF492E Vanya and Field

tin 翻譯 gis clu 而且 ans print 由於 -m

題目大意:

一天,Vanya 來到了一片滑稽樹林中,準備采摘滑稽果。滑稽樹林可看作一個 n×n 的正方形,其中 m 個點上有滑稽果,某些點沒有。(註意一個點上可能有多個滑稽果)

Vanya會沿向量 (dx,dy)(dx,dy) 方向移動。也就是說,如果Vanya在 (x,y) 處,她將移動到 ((x+dx) mod n,(y+dy) mod n)((x+dx) mod n,(y+dy) mod n) 處。每到一個點,她會拿走該點所有滑稽果。(dx,dy 為定值(輸入中給出),且 gcd(n,dx)=gcd(n,dy)=1)

由於滑稽樹林太巨了,當Vanya走到一個她走到過的點時,她就會停止走動。

現在Vanya想知道她怎麽走才能拿到最多的滑稽果。

(來自巨佬interestinLSY的翻譯)

啊對了,n<= 10 ^ 5。

可見暴力不行吶

容易證明,(x, y)點在移動n次一定會回到原點,即每一條路線的移動周期是n。而且可以得出,在這個移動周期內,每一個點x, y 分別對n取模得到的值都不相同,也就是說,一條路線內每個點橫縱坐標兩兩不相同。

那麽我們只要求出每一個有果子的點屬於哪一條路線就可以了。

首先可以隨意選一條路線(為了方便,稱為基線),將他的每一個點求出來,得到一個y已知時x的映射,而且上文已經說道,對於每一個0 <= y < n,都有唯一的x與之對應。

求出一條路線後,其他路線就可以由基線平移得到,所以對於每一個有果子的點,只要求出他和基線上y相同的點的距離,即第幾條路線,然後開一個類似桶的數組記錄每一條路線收獲的果子數量,答案取max即可。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<stack>
 9
#include<queue> 10 #include<vector> 11 using namespace std; 12 #define enter printf("\n") 13 #define space printf(" ") 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps = 1e-8; 19 const int maxn = 1e6 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) 26 { 27 ans = ans * 10 + ch - 0; ch = getchar(); 28 } 29 if(last == -) ans = -ans; 30 return ans; 31 } 32 inline void write(ll x) 33 { 34 if(x < 0) x = -x, putchar(-); 35 if(x >= 10) write(x / 10); 36 putchar(x % 10 + 0); 37 } 38 39 int n, m, dx, dy; 40 41 int a[maxn], b[maxn], ans = 0, pos; 42 int pnt[2][maxn]; 43 44 int main() 45 { 46 n = read(); m = read(); dx = read(); dy = read(); 47 for(register int i = 0, j = 1; j < n; i = (i + dy) % n, ++j) //求基線 48 a[(i + dy) % n] = (a[i] + dx) % n; 49 for(register int i = 1; i <= m; ++i) 50 { 51 int x = read(), y = read(), t; 52 t = (x - a[y] + n) % n; //算距離 53 b[t]++; 54 pnt[0][t] = x; pnt[1][t] = y; //第t條路線一定經過的點就是(x, y) 55 } 56 for(register int i = 0; i < n; ++i) 57 if(b[i] > ans) {ans = b[i]; pos = i;} 58 write(pnt[0][pos]); space; write(pnt[1][pos]); enter; 59 return 0; 60 }

CF492E Vanya and Field