Hdu 6209 The Intersection(Stern-Brocot tree+二分)

来源:互联网 发布:花都金蝶软件代理商 编辑:程序博客网 时间:2024/04/25 12:11
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6209

思路:



1.Stern-Brocot树可以构成所有有理数。

2.对于每次在m1/n1,m2/n2中插入(m1+m2)/(n1+n2)构成下一排。

3.Stern-Brocot树构成的所有分数均为最简分数,即gcd(m,n)==1。

其中,第N排的真分数部分为N阶Farey序,满足对于连续的分数m1/n1,m2/n2,必有m1/n1<m2/n2。


由此,取该数的小数部分,二分答案即可。

注意:此题卡long double。

#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;long double lt;int ansl,ansr;void solve(int l1,int r1,int l2,int r2){    if(l1==l2&&r1==r2) return ;    if(fabs((long double)l1/r1-lt)<fabs((long double)ansl/ansr-lt))    {        ansl=l1;        ansr=r1;    }    if(fabs((long double)l2/r2-lt)<fabs((long double)ansl/ansr-lt))    {        ansl=l2;        ansr=r2;    }    int ml=(l1+l2);    int mr=(r1+r2);    if(mr>100000) return ;    if((long double)ml/mr<lt) solve(ml,mr,l2,r2);    else solve(l1,r1,ml,mr);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        int flag=0,k;        scanf("%d",&k);        ansl=ansr=1;        long double tmp=pow((long double)k,(long double)2.0/3.0);        lt=tmp-(int)floor(tmp);        solve(0,1,1,1);        printf("%d/%d\n",(int)floor(tmp)*ansr+ansl,ansr);    }    return 0;}