题目描述
(a,b,c leq 10^{18})
题解
先除gcd
假设给出a和b,构出b,2b,4b,8b...2^kb(2^kb<a),那么显然是(a,b),(a-b,b),(a,a-2b)来使b*2
可以尝试每次乘4,发现结果是一样的
辗转相除求出gcd之后即可构出1,2,4,8...,之后减一下即可
用map去重,否则过不了
时间看似是log^2的,但是感受一下发现b每*2模完之后就可以少一次,因此应该是log*常数级别的
code
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define ll long long
//#define file
using namespace std;
ll ans[401][2],A,B,C,s,Ans,t;
map<ll,bool> hs;
int i,j,k,l;
ll gcd(ll x,ll y) {ll r=x%y; while (r) x=y,y=r,r=x%y; return y;}
void add(ll x,ll y) {if (!hs[x-y]) ++Ans,ans[Ans][0]=x,ans[Ans][1]=y,hs[x-y]=1;}
void swap(ll &x,ll &y) {ll z=x;x=y;y=z;}
void work(ll x,ll y,bool bz)
{
ll Y=y;
while (Y*2<x)
add(x,Y),add(x-Y,Y),add(x,x-2*Y),Y*=2;
if (bz)
{
while (Y>=y)
{
if (x>Y) add(x,Y),x-=Y;
Y/=2;
}
}
}
void Work()
{
ll a=A,b=gcd(A,B),r=A%B;
while (r) work(A,B,1),A=B,B=r,r=A%B;
work(a,b,0);
while (b*2<a) b*=2;
while (a!=C)
{
if (a-b>=C) add(a,b),a-=b;
b/=2;
}
}
int main()
{
#ifdef file
freopen("uoj216.in","r",stdin);
#endif
scanf("%lld%lld%lld",&A,&B,&C);s=gcd(A,B);
if (C%s || max(A,B)<C) {printf("-1
");return 0;}
A/=s,B/=s,C/=s;
if (A<B) swap(A,B);
hs[A]=hs[B]=1;
Work();
printf("%lld
",Ans);
fo(i,1,Ans) printf("%lld %lld
",ans[i][0]*s,ans[i][1]*s);
fclose(stdin);
fclose(stdout);
return 0;
}