码迷,mamicode.com
首页 > 其他好文 > 详细

【伪题解】线段树什么最讨厌了 (DFS)

时间:2015-09-25 17:53:16      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

Description:

小丫最近学习了线段树,但是由于她的智商比较低,运用的还不是很熟
练。于是小R给了她一点练习题训练,其中有一道是这样的。
这是小R写的线段树的一段建树代码:

技术分享

只要调用buildtree(1,0,n)就可以得到一颗线段树了。显然,一颗线段树一
共有O(n)个节点,因为每一个节点都代表了一个不同的区间,所以线段树
上一共出现了O(n)个不同的区间。
现在小R给了你一个区间【l ;r 】 ,想要你告诉他一个最小的n使得区间【l ;】
出现在了用buildtree(1,0n)建出来的线段树中。

Input

第一行输入一个正整数丁表示数据组数。
接下来丁行每行三个整数L;R; lim表示一组询问,如果对于所有的0 <= n
<= lim都不存在满足条件的解,输出一1即可。

Output

对于每组询问输出一个答案。

Sample Input

2
0 5 10
6 7 10

Sample Output
5
7

 

这道题我没测,所以具体不知道是否能全过掉数据,但思路肯定是正确的。

你可以任意举一个0到n,画画所建出来的线段树,你会发现,这道题要求的不过是这个区间从哪里分出来,以此类推。

我们发现,对于任何一个子区间,分出它的母区间都有有四种可能((left-1)*2-right,right)(((left-1)*2-right+1,light)

(left,right*2-left),(left,right*2-left+1),于是就是一个搜索,当然不会超时.一些小细节啊,边界啊,自己去考虑,比较容易想到.

 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 ifstream fin("tree.in");
 8 ofstream fout("tree.out");
 9 
10 int cnt_zu=0;
11 
12 long long int dfs(int left,int right,int lim){
13   if(left==0)return right;
14   if(right>lim)return lim+1;
15   int l=0,r=0;
16   long long ans=0x7fffffff;    
17   l=(left-1)*2-right;
18   r=right;
19   if((r+l)/2==left-1)ans=min(ans,dfs(l,r,lim));
20   if((r+l+1)/2==left-1)ans=min(ans,dfs(l+1,r,lim));
21   l=left;
22   r=right*2-left;
23   if((r+l)/2==right)ans=min(ans,dfs(l,r,lim));
24   if((r+l+1)==right)ans=min(ans,dfs(l,r+1,lim));
25   return ans;    
26 }
27 
28 int main( ){
29  fin>>cnt_zu;
30  for(int x=1;x<=cnt_zu;x++){
31   int left=0,right=0;
32   int lim=0;
33   fin>>left>>right>>lim;    
34   long long int ans=dfs(left,right,lim);    
35   if(ans>lim)ans=-1;
36   cout<<ans<<endl;
37   fout<<ans<<endl;
38  }    
39  return 0;    
40 }

 

【伪题解】线段树什么最讨厌了 (DFS)

标签:

原文地址:http://www.cnblogs.com/Ateisti/p/4838695.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!