jzoj4208. 线段树什么的最讨厌了(B组——Day4)
题目
Description
小Y 最近学习了线段树,但是由于她的智商比较低,运用的还不是很熟练。于是小R 给了她一点练习题训练,其中有一道是这样的。
这是小R 写的线段树的一段建树代码:
只要调用buildtree(1,0,n) 就可以得到一颗线段树了。显然,一颗线段树一共有O(n) 个节点,因为每一个节点都代表了一个不同的区间,所以线段树上一共出现了O(n) 个不同的区间。
现在小R 给了你一个区间[l; r],他想要你告诉他一个最小的n 使得区间[l; r] 出现在了用buildtree(1,0,n) 建出来的线段树中。
Input
第一行输入一个正整数T 表示数据组数。
接下来T 行每行三个整数L;R; lim 表示一组询问,如果对于所有的0 <= n <= lim 都不存在满足条件的解,输出-1 即可。
Output
对于每组询问输出一个答案。
Sample Input
2
0 5 10
6 7 10
Sample Output
5
7
Data Constraint
解析
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int ans,l,r,lim;
void dfs(int l,int r) {
if (r>lim) return;
if (r>=ans) return;
if (l==0){
ans=r;
return;
}
int cnt=r-l+1;
if (l-cnt==0 || l-cnt>=cnt+cnt) dfs(l-cnt,r);
if (l-cnt==1 || l-cnt-1>=cnt+cnt+1) dfs(l-cnt-1,r);
if (l>=cnt+cnt-1) dfs(l,r+cnt-1);
if (l>cnt+cnt) dfs(l,r+cnt);
}
int main() {
int t;
scanf("%d",&t);
while (t){
t--;
scanf("%d%d%d",&l,&r,&lim);
ans=2e9;
dfs(l,r);
if (ans==2e9) printf("-1\n");
else printf("%d\n",ans);
}
}