题目链接
题目解法
考虑不存在平行四边形的判断条件,则应当为:
对于任意
(
i
≠
j
)
(i\ne j)
(i=j) ,
P
i
−
P
j
P_i-P_j
Pi−Pj 得到的向量两两不同。
注意到题目保证了 N + 1 N+1 N+1 是质数,不妨猜想构造方式与原根 g g g 有关。
考虑如下构造:
P
i
=
(
i
,
g
i
%
N
)
P_i=(i,g^i\% N)
Pi=(i,gi%N)
则
P
i
−
P
j
=
(
i
−
j
,
g
j
(
g
i
−
j
−
1
)
%
N
)
P_i-P_j=(i-j,g^j(g^{i-j}-1)\% N)
Pi−Pj=(i−j,gj(gi−j−1)%N)
不难发现对于 i − j i-j i−j 相等的 ( i , j ) (i,j) (i,j) ,其对应的 g j ( g i − j − 1 ) % N g^j(g^{i-j}-1)\% N gj(gi−j−1)%N 两两不同。
时间复杂度 O ( T × N ) O(T\times N) O(T×N) 。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e3 + 5;
typedef long long ll;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
x = 0; int f = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
x *= f;
}
bool check(int n, int x) {
static bool vis[MAXN];
memset(vis, false, sizeof(vis));
for (int i = 1, res = 1; i <= n; i++, res = res * x % (n + 1)) {
if (vis[res]) return false;
vis[res] = true;
}
return true;
}
int main() {
int T; read(T);
while (T--) {
int n; read(n);
int g = 2; while (!check(n, g)) g++;
for (int i = 1, res = 1; i <= n; i++, res = res * g % (n + 1))
printf("%d %d\n", i, res);
}
return 0;
}