HDU 5323 Solve this interesting problem DFS

1 篇文章 0 订阅
1 篇文章 0 订阅

题意

问最小的 n ,使得线段树0~n范围有一个节点的范围是包括恰好为L~R的!

分析:

其实这道题目大家多多少少会想到向上搜索所有的节点,但是其实就是一直DFS
关键就是 剪 枝 很重要!

对于 一个 LR L − R 的区间,我们有 4 4 种情况向父亲节点深搜:
1.[l,2rl]
2. [l,2r+1l] [ l , 2 ∗ r + 1 − l ]
3. [(l1)2r,r] [ ( l − 1 ) ∗ 2 − r , r ]
4. [(l1)2+1r,r] [ ( l − 1 ) ∗ 2 + 1 − r , r ]

而且有剪枝就是这个:

 if(ans != INF && R >= ans) return ;
 //以为向上过程之中,这 4 种情况都是R区间只增不减!

关键就是这个顺序应该怎么搞,所以应该是往左边先搜,这样得出来的ans 才会有剪枝的价值,不然是会MLE,TLE 的!
于是顺序就是
4 3 2 1 这样DFS

代码:

#pragma GCC optimize(3)
#include<cstring>
#include<stdio.h>
#include <iostream>
#include<algorithm>
#include <vector>
#define P pair<int,int>
#define INF 0x3f3f3f3f
// #define MAXN = 20050-
#define ll long long
using namespace std;
ll L,R,ans;
void DFS(ll L,ll R)
{
    if(L == 0) return (void)(ans = min(ans,R));
    if(ans != INF && R >= ans) return ;
    if(R < 0 || L<0) return ;
    if(R-L+1 > (L-1) <<1 ) return ;
   // 顺序是不能变的! 因为只有往左搜 R>=ans return 的剪枝才是有用的!
    DFS(L,(R<<1) - L);
    DFS(L,(R<<1) - L + 1); 
    DFS(((L-1)<<1) - R , R); 
    DFS(((L-1)<<1) - R +1 , R);
    // L_ + R / 2 == L-1 ---> L_ = 2*(L-1) - R


}
int main()
{
    while(~scanf("%lld%lld",&L,&R))
    {
        ans = INF;
        DFS(L,R);
        printf("%lld\n", (ans==INF)?-1:ans);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值