HDU 5323(DFS)

Have you learned something about segment tree? If not, don’t worry, I will explain it for you. 
Segment Tree is a kind of binary tree, it can be defined as this: 
- For each node u in Segment Tree, u has two values:  Lu Lu and  Ru Ru
- If  Lu=Ru Lu=Ru, u is a leaf node. 
- If  LuRu Lu≠Ru, u has two children x and y,with  Lx=Lu Lx=Lu, Rx=Lu+Ru2 Rx=⌊Lu+Ru2⌋, Ly=Lu+Ru2+1 Ly=⌊Lu+Ru2⌋+1, Ry=Ru Ry=Ru
Here is an example of segment tree to do range query of sum. 



Given two integers L and R, Your task is to find the minimum non-negative n satisfy that: A Segment Tree with root node's value  Lroot=0 Lroot=0 and  Rroot=n Rroot=n contains a node u with  Lu=L Lu=L and  Ru=R Ru=R
Input
The input consists of several test cases. 
Each test case contains two integers L and R, as described above. 
0LR109 0≤L≤R≤109 
LRL+12015 LR−L+1≤2015 
Output
For each test, output one line contains one integer. If there is no such n, just output -1.
Sample Input
6 7
10 13
10 11
Sample Output
7
-1
12


题解:

DFS  往上枚举,二叉树的节点特性就是 左节点区间长度 - 右节点区间长度 =  0 | 1 两个值。

所以向上反推的时候可能有四种情况

向四个方向搜索分别是
[l,r+len]
[l,r+len-1]
[l-len,r]
[l-len-1,r]
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <queue>
#define mem(p,k) memset(p,k,sizeof(p));
#define rep(i,j,k) for(int i=j; i<k; i++)
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 0x6fffffff
#define ll long long
using namespace std;
const int mod=1e9+7;
char s[2100];
int bk[110],f[50000];
ll n,m,k,minn,maxx,ans,cur,sum,x,y;
int nex[4][2]={0,1,1,0,0,-1,-1,0};
void dfs(ll l,ll r){//cout<<l<<r<<endl;
    if(l==0){
        if(minn==-1){
            minn=r;
        }
        else if(r<minn)minn=r;
        return ;
    }
    if(minn!=-1&&r>minn)return;//剪枝
    int le=r-l+1;
    if(l<le)return ;
    if((l-le)>=0){
        dfs(l-le,r);
    }
    if((l-le-1)>=0){
        dfs(l-le-1,r);
    }
    if(minn==-1||r+le<minn){//剪掉当MINN 小于 R 时
        dfs(l,r+le);
    }
    if(minn==-1||r+le-1<minn){//...
        dfs(l,r+le-1);
    }
}
int main()
{
    ll l,r;
    while(cin>>l>>r){
        minn=-1;
        dfs(l,r);
        cout<<minn<<endl;
    }


    return 0;
}
//freopen("C:\\Users\\LENOVO\\Desktop\\read.txt","r",stdin);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值