101,1000,899,101,798,697,101,596,495,101,394,293,101,192,91,101,.....
7,4,3,1,2,...
不难发现
①:假如当前只有
a,b,l=abs(a−b)
②:则后续必然出现
{k|min(a,b,l)<=k<=max(a,b,l)且k%min(a,b,l)==0}
③:
ans+=max(a,b,l)−min(a,b,l)min(a,b,l)
这样的
k
出现完后,紧跟着
于是设
a=max(a,b,l)%min(a,b,l),b=min(a,b,l),重复以上步骤
因为对任意a>=b,满足a%b<a2,所以每次最大值都会减半,log(n)次操作后=0
复杂度O(log(n))
Ps:注意特判,不要mod 0
#include<stdio.h>
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))
using namespace std;
const int inf=1e9+7;
const int N = 1e5;
inline ll max(ll a,ll b,ll c){
return max(a,max(b,c));
}
inline ll min(ll a,ll b,ll c){
return min(a,min(b,c));
}
ll slove(ll a,ll b){
if(a==0&&b==0){
return 1;
}
ll l=abs(a-b);
ll sum=0;
if(min(a,b,l)==0){
return sum+2;
}
while(max(a,b,l)%min(a,b,l)!=0){
sum+=max(a,b,l)/min(a,b,l);
ll ta=min(a,b,l);
ll tb=max(a,b,l)%min(a,b,l);
a=ta,b=tb;
l=abs(a-b);
if(min(a,b,l)==0){
return sum+2;
}
}
sum+=max(a,b,l)/min(a,b,l)+1;
return sum;
}
int main()
{
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w.txt","w",stdout);
int T;
scanf("%d",&T);
for(int tt=1;tt<=T;++tt){
ll a,b;
scanf("%lld%lld",&a,&b);
ll ans=slove(a,b);
printf("Case #%d: %lld\n",tt,ans);
}
return 0;
}