hdu5323 Solve this interesting problem(DFS关于线段树中的一些性质和规律)

Solve this interesting problem

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


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.

hdu5323 Solve this interesting problem(DFS关于线段树中的一些性质和规律) - NatureRan - NatureRan


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=ncontains 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
LR?L+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
 

题意:一个线段树所有叶子节点编号为0~n,给出l和r,求出最小的n使得存在一个节点的左值等于l,右值等于r
关于线段树的一些性质和规律:如果存在一个节点其左值为l右值为r,那么他的父亲节点的左右值有四种可能,即
[l,2*l+1]
[l,2*r]
[2*(l-1)-r,r]
[2*(l-1)-r+1,r]
所以题目给出l和r的值后,按着四个方向进行DFS,剪枝条件:
当已找到一个合适的mi值后,r>=mi的值,return(如果只判断r>mi的话就会超时)
l<0 那肯定return了
该节点的区间长度即   r-l+1    如果大于   l      则return,  原因:将(l,r)看做这个线段树的右子树的话,左子树的长度即为l,右子树的长度为(r-l+1) 线段树性质:左子树区间长度大于等于右子树的区间长度

 
   

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
long long mi;
long long L,R;
long long minn(long long a,long long b){
return a<b?a:b;
}
void DFS(long long l,long long r){
if(l==0){
if(mi==-1) mi=r;
else mi=minn(mi,r);
}
if(mi!=-1&&r>=mi) return;
if(l<0) return;
if(r-l+1>l) return ;
DFS((l-1)*2-r,r) ;
DFS((l-1)*2+1-r,r) ;
DFS(l,r*2-l) ;
DFS(l,r*2+1-l) ;
}
int main(int argc, char *argv[])
{

while(scanf("%lld%lld",&L,&R)!=EOF){
mi=-1;
DFS(L,R);
printf("%lld\n",mi);
}
return 0;
}



猜你喜欢

转载自blog.csdn.net/nature_ran/article/details/79125323
今日推荐