官方题解里提到验题人的一种期望更优的作法,感觉很有意思。
考虑从
- 若
a<b ,交换a 和b 。 - 否则,
a-=b 。
观察到初始时
但更相减损术不能保证复杂度。于是我们不断随机
因为 2 操作与 3 操作互逆,那么显然
下面是代码:
#include <cstdio>
#include <algorithm>
#include <chrono>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MAXL=220;
int get_len(int a, int b)
{
if (b==0) return 0;
return get_len(b, a%b)+a/b+1;
}
int get_path(int u, int p, bool* c)
{
int a, b, l=0;
do
{
b=rng()%(p-1)+1;
a=1ll*u*b%p;
} while (get_len(a, b)>100);
while (b!=0)
if (a<b) c[++l]=0, swap(a, b);
else a-=b, c[++l]=1;
return l;
}
bool c1[MAXL], c2[MAXL];
int main()
{
// freopen("E.in", "r", stdin);
// freopen("E.out", "w", stdout);
int u, v, p;
scanf("%d%d%d", &u, &v, &p);
int l1=get_path(u, p, c1);
int l2=get_path(v, p, c2);
printf("%d\n", l1+l2);
for (int i=1; i<=l1; i++) printf("%d ", c1[i]?2:3);
for (int i=l2; i>=1; i--) printf("%d ", c2[i]?1:3);
putchar('\n');
return 0;
}