传送门
Problem Description Little X, Little Y and Little Z are playing checkers when Little Y is annoyed. So he wants to make the chessboard much bigger. Although Little Z insists the original version, Little X stands by Little Y. After they enlarge the chessboard, the chessboard turns to an infinite line. |
这道题的思路也太难想到了吧,一开始还以为是数学题,居然利用LCA的思想求解的。。。
具体解析博客:http://www.cnblogs.com/scau20110726/archive/2013/06/14/3135024.html
代码:
///#include<bits/stdc++.h>
///#include<unordered_map>
///#include<unordered_set>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<set>
#include<stack>
#include<map>
#include<new>
#include<vector>
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
struct node
{
ll p[4];
ll depth;
}a,b,root_a,root_b;
bool judge(node x,node y)
{
if(x.p[1]==y.p[1]&&x.p[2]==y.p[2]&&x.p[3]==y.p[3])
return true;
return false;
}
node find_root(node &x)
{
node ans=x;
ans.depth=0;
while(abs(ans.p[1]-ans.p[2])!=abs(ans.p[3]-ans.p[2]))
{
ll left=abs(ans.p[1]-ans.p[2]);
ll right=abs(ans.p[3]-ans.p[2]);
if(left>right)
{
ll mul=(left-1)/right;
x.depth+=mul;
ans.p[2]-=mul*right;
ans.p[3]-=mul*right;
}
else
{
ll mul=(right-1)/left;
x.depth+=mul;
ans.p[1]+=mul*left;
ans.p[2]+=mul*left;
}
}
return ans;
}
void jump(node &x,ll depth)
{
ll cnt=0;
while(cnt<depth)
{
ll left=abs(x.p[1]-x.p[2]);
ll right=abs(x.p[3]-x.p[2]);
ll sub=depth-cnt;
if(left>right)
{
ll mul=(left-1)/right;
ll minn=min(mul,sub);
x.p[2]-=minn*right;
x.p[3]-=minn*right;
cnt+=minn;
}
else
{
ll mul=(right-1)/left;
ll minn=min(mul,sub);
x.p[1]+=minn*left;
x.p[2]+=minn*left;
cnt+=minn;
}
}
x.depth-=depth;
}
ll solve()
{
node x,y;
ll l=0,r=a.depth;
ll ans=0;
while(l<=r)///二分 向上跳跃的距离
{
ll mid=(l+r)>>1;
x=a;
y=b;
jump(x,mid);
jump(y,mid);
if(judge(x,y))
{
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
return ans;
}
void init()
{
a.depth=b.depth=0;
sort(a.p+1,a.p+4);
sort(b.p+1,b.p+4);
}
int main()
{
while(cin>>a.p[1]>>a.p[2]>>a.p[3])
{
cin>>b.p[1]>>b.p[2]>>b.p[3];
init();///初始化
///两种状态的根
root_a=find_root(a);
root_b=find_root(b);
if(!judge(root_a,root_b))
printf("NO\n");
else
{
///将两种状态的深度调成一致
ll add=abs(a.depth-b.depth);
if(a.depth>b.depth)
jump(a,add);
else
jump(b,add);
///二分
ll res=solve();
printf("YES\n%lld\n",res*2+add);
}
}
return 0;
}