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

181 篇文章 0 订阅
63 篇文章 0 订阅


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 7 10 13 10 11
 

Sample Output
  
  
7 -1 12
 

Source
 


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


AC code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<cmath>
#define LL long long
#define MAXN 1000010
using 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)//jianzhi
		return;
	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");
		else
			printf("%I64d\n",ans);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林下的码路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值