多校第三场 1006 hdu 5323 Solve this interesting problem(dfs)

题目链接:

点击打开链接

题目大意:

给出一个区间,问存在以这个区间为左右区间的节点的最小的线段树。

题目分析:

首先对于线段树的一个节点,假设它的区间是[l,r],那么它的父亲的区间可能是

[L,2*R-L+1]   ,     [L,2*R-L]   ,  [2*L-2-R,R]   , [2*L-R-1,R]

那么暴力求解即可。

那么暴力求解的复杂度是什么呢?

首先因为L/区间长度<=2015,所以最多向上翻2^11倍,每次再一直找左区间,又是一个最坏2^11的复杂度,所以最坏复杂度O(2^11)

所以暴力求解是可以的。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <algorithm>

using namespace std;

typedef long long LL;
const LL INF = 1e18+7;
LL ans = INF;
LL l,r;

void dfs ( LL l , LL r )
{
    if ( r >= ans ) return;
    if ( l < 0 || r < l ) return;
    if ( l == 0 )
    {
        ans = min ( ans , r );
        return;
    }
    if ( r - l + 1 > l ) return;
    dfs ( l , (r<<1)-l+1 );
    dfs ( l , (r<<1)-l );
    dfs ( (l<<1)-2-r , r );
    dfs ( (l<<1)-r-1 , r );

}

int main ( )
{
    while (~scanf ( "%I64d%I64d" , &l , &r ))
    {
        ans = INF;
        if ( l == r || l == 0 ) ans = r;
        else dfs ( l , r );
        if ( ans != INF )
            printf ("%I64d\n" , ans );
        else puts ( "-1" );
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值