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

这篇博客介绍了如何利用Stern-Brocot树构造所有有理数,并结合二分搜索解决HDU 6209问题。在Stern-Brocot树中,每排的真分数部分构成N阶Farey序,保证了分数的增序。通过小数部分比较,可以有效进行二分查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目地址: 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;
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值