题意:有一个边长为 N(2<=N<=10^12)的由镜子组成的等边三角形,设结点为a,b,c(这里的a,b,c自己在题面的图上找),从ab上取一点p,使得ap=X(1<=X<=N-1),从p水平向右发射一条光线,经过若干次反射,回到p点。光线会被自己走过的路线反射,求最后回到p点时,光线移动的距离。
一个很简单的题解是 (听说打表找规律可以很快找出来?)。官方题解的图看起来很直观所以也就不打算解释了QAQ
然而我写的模拟…
我们很容易地可以发现光线是在平行四边形中移动的。不妨设短的一条边为a,长的一条边为b。那么下一个平行四边形的边长就成为b%a和a,直到a为0。一次的路程也就显然是
。代码没直接写取模但是也就是取模了。因为方向是先左上再左下或者先左上再往右的所以到达了过后要减回来。然后一开始两步没有算要加回来。
时间复杂度不清楚,大概和gcd差不多。
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
LL n,x,ans,x1,x2;
int main()
{
scanf("%lld%lld",&n,&x);
ans=n;
x1=x,x2=n-x;
while(1)
{
if(x1<x2) swap(x1,x2);
if(!x2) break;
if(x1%x2==0) ans-=x2;
ans+=x2*(x1/x2)*2;
x1-=x2*(x1/x2);
}
printf("%lld\n",ans);
}