可以发现c肯定是Gcd的倍数
那么可以先用倍增模拟取模算出gcd
然后用gcd倍增出c
考试时没特判c>a && c>b 爆炸 20分
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> abcd;
abcd Stack[100005];
set<ll> Set;
int pnt;
inline void doit(ll a,ll b){
if (Set.find(a-b)!=Set.end()) return;
Stack[++pnt]=abcd(a,b);
Set.insert(a-b);
}
inline void Calc(ll a,ll b){
ll tmp=b;
while (tmp*2<=(a/b)*b)
{
doit(a,tmp);
doit(a-tmp,tmp);
doit(a,a-tmp-tmp);
tmp<<=1;
}
ll k=a/b; ll t2=a;
for (int p=0;(1LL<<p)<=k;p++)
if (k>>p&1)
{
doit(t2,(1LL<<p)*b);
t2-=(1LL<<p)*b;
}
}
ll a,b,c,d,g;
void Gcd(ll a,ll b){
if (a%b==0) { g=b; return; }
Calc(a,b);
Gcd(b,a-(a/b)*b);
}
int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
scanf("%lld%lld%lld",&a,&b,&c);
if (a<b) swap(a,b);
if (c==a || c==b) return printf("0\n"),0;
if (c>a) return printf("-1\n"),0;
Gcd(a,b);
if (c%g!=0) return printf("-1\n"),0;
d=c/g;
ll tmp=g;
while (tmp*2<=c)
{
doit(a,tmp);
doit(a-tmp,tmp);
doit(a,a-tmp-tmp);
tmp<<=1;
}
ll t2=a;
for (int p=0;(1LL<<p)<=d;p++)
if (d>>p&1)
{
doit(t2,(1LL<<p)*g);
t2-=(1LL<<p)*g;
}
doit(a,t2);
if (pnt>400) return printf("-1\n"),0;
printf("%d\n",pnt);
for (int i=1;i<=pnt;i++)
printf("%lld %lld\n",Stack[i].first,Stack[i].second);
return 0;
}