Solve this interesting problem(线段树逆二分模拟的DFS递归操作)

来源:互联网 发布:淘宝开店的优势 编辑:程序博客网 时间:2024/05/22 12:47


Link:http://acm.hdu.edu.cn/showproblem.php?pid=5323


Solve this interesting problem

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1696    Accepted Submission(s): 503


Problem Description
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 and Ru.
- If Lu=Ru, u is a leaf node. 
- If LuRu, u has two children x and y,with Lx=Lu,Rx=Lu+Ru2,Ly=Lu+Ru2+1,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 and Rroot=n contains a node u with Lu=L and Ru=R.
 

Input
The input consists of several test cases. 
Each test case contains two integers L and R, as described above.
0LR109
LRL+12015
 

Output
For each test, output one line contains one integer. If there is no such n, just output -1.
 

Sample Input
6 710 1310 11
 

Sample Output
7-112
 

Source
2015 Multi-University Training Contest 3
 


分析:要做这题,首先需要知道线段树的构建过程,然后只要对构建线段树的逆向操作进行模拟即可,DFS递归时注意左右区间边界条件。


AC code:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<map>#include<queue>#include<cmath>#define LL long long#define MAXN 1000010using namespace std;const LL INF=0x3f3f3f3f;LL L,R,ans;void dfs(LL l,LL r){if(l<=0||r>=2*R){if(l==0){ans=min(ans,r);}return;}int len=r-l+1;if(len>l)//jianzhireturn;dfs(l-len,r);dfs(l-len-1,r);dfs(l,r+len);if(len>1)dfs(l,r+len-1);}int main(){while(scanf("%I64d%I64d",&L,&R)!=EOF){ans=INF;dfs(L,R);if(ans==INF)printf("-1\n");elseprintf("%I64d\n",ans);}return 0;}


0 0
原创粉丝点击