cf 的题第一次遇到了溢出long long 的情况,这道题目,通过限制他超出long long 的情况,防止溢出,并且在计算的时候,double 的长度更长一点,在大数相乘的时候采用double 防止溢出,并且简化题目

题意:给你一个t ,w,b, w,b,是两个人的步长,t 是路程总长度,当两人速度相同的时候,在终点设置一个深渊,任何人都不能跨过去,最后谁距离终点最近谁为赢家,问两人平局的概率有多少
t,w,b <1e18

思路分析:这个题的思路很简单,t对于w和b取余相同则平局,只要求最小公倍数lcm,在 klcm ~ klcm+min(w,b) 之间的数对于w,b取余都相同,其中 1kt/lcm ,当k=0的时候就是从0到min(t,min(b,w)-1 );
如果这个题不存在溢出的话,这样做就应该可以了,但是由于t,w,b的数据非常大,我们可以判断一下,如果 t<lcm(w,b) 的情况下只要考虑k=0的情况就可以了,这样的话,我们只要在这里用double 计算一下lcm就可以了
tlcm(w,b) 的时候,因为t 在long long 范围内,所以 lcm(w,b)也在long long 范围内,所以不会溢出

#include <bits/stdc++.h>
using namespace std;
const int maxn=1500;
const int inf=0x3f3f3f3f;
typedef unsigned long long ull;
ull t,a,b,g;
int main()
{
    cin>>t>>a>>b;
    ull k=min(a,b);
    ull a1=a/__gcd(a,b);
    ull b1=b/__gcd(a,b);
    ull g=a1*b1*__gcd(a,b);
    ull p,q;
    ull ans=0;
    if((double)t<(double)a1*(double)b1*(double)__gcd(a,b))
    {
    ans=min(t,min(a-1,b-1));
    }
    else
    {
         ans=(t/g)*k+ min(k,t%g+1) -1;
    }
    //cout<<ans<<endl;
    ull fact=__gcd(ans,t);
    p=ans/fact;
    q=t/fact;
    cout<<p<<"/"<<q<<endl;

    return 0;
}