给出一个点
M
0
M_{0}
M0,以及奇数个点
A
0
,
A
1
.
.
.
A
n
−
1
A_{0},A_{1}...A_{n-1}
A0,A1...An−1,生成新的一个点的方法是
M
i
M_{i}
Mi是
M
i
−
1
M_{i-1}
Mi−1关于
A
(
i
−
1
)
%
n
A_{(i-1)\%n}
A(i−1)%n的对称点,然后求第
k
k
k个点的坐标。
注意到横坐标和纵坐标实际上是独立的。所以拆成两个相同的子问题。而我们发现对于这个子问题,奇数个点对称
2
n
2n
2n次恰好会到原来的点。
因此只要一遍模拟出循环节,对询问的答案取模即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=2e5+7;
int x[N],y[N];
int ans1[N],ans2[N];
int tot1=0,tot2=0;
int main() {
int n;
ll d;
scanf("%d%lld",&n,&d);
int mx,my;
scanf("%d%d",&mx,&my);
for(int i=0;i<n;i++)
scanf("%d%d",&x[i],&y[i]);
for(int i=0;i<n;i++) {
mx=2*x[i]-mx;
ans1[++tot1]=mx;
}
for(int i=0;i<n;i++) {
mx=2*x[i]-mx;
ans1[++tot1]=mx;
}
for(int i=0;i<n;i++) {
my=2*y[i]-my;
ans2[++tot2]=my;
}
for(int i=0;i<n;i++) {
my=2*y[i]-my;
ans2[++tot2]=my;
}
d=(d-1)%(2*n)+1;
printf("%d %d\n",ans1[d],ans2[d]);
return 0;
}