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 Lu≠Ru , 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 .
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 Lu≠Ru , 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 .
Each test case contains two integers L and R, as described above.
0≤L≤R≤109
LR−L+1≤2015
6 7 10 13 10 11
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);