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

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 }
时间: 2024-10-13 02:35:37

【伪题解】线段树什么最讨厌了 (DFS)的相关文章

POJ2182题解——线段树

POJ2182题解——线段树 2019-12-20 by juruoOIer 1.线段树简介(来源:百度百科) 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN).而未优化的空间复杂度为2N,实际应用时一般还要开4N的数组以免越界,因此有时需要离散化让空间压缩. 2.线段树实际应用 上面的都是些基本的线段树结构,但只有这些并不能做什么,就好比一个程序有

理想乡题解 (线段树优化dp)

题面 思路概述 首先,不难想到本题可以用动态规划来解,这里就省略是如何想到动态规划的了. 转移方程 f[i]=min(f[j]+1)(max(i-m,0)<=j<i 且j符合士兵限定) 注意要用 max(i-m,0)以防止越界 我们先用两个数组sl,sa分别统计1~i个士兵中有多少个Lencer和Archer 然后在max(i-m,0)中寻找符合条件的j (1).两种士兵相差不超过k. 这个好说abs((sl[i]-sl[j])-(sa[i]-sa[j]))<=k 不要忘了第二种情况!!

[题解]线段树专题测试2017.1.21

很单纯的一道线段树题.稍微改一下pushDown()就行了. Code(线段树模板竟然没超100行) 1 #include<iostream> 2 #include<sstream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstdlib> 6 #include<cstring> 7 #include<cctype> 8 #include<queue> 9

Vijos1448题解---线段树+括号法

描述 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的……如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现有两个操作:K=1,K=1,读入l.r表示在区间[l,r]中种上一种树,每次操作种的树的种类都不同K=2,读入l,r表示询问l~r之间能见到多少种树(l,r>0) 输入格式 第一行n,m表示道路总长为n,共有m个操作接下来m行为m个操作 输出格式 对于每个k=2输出一个答案 样例输入 5 4 1 1 3 2 2 5 1 2 4 2 3 5

codedecision P1112 区间连续段 题解 线段树

题目描述:https://www.cnblogs.com/problems/p/P1112.html 题目链接:http://codedecision.com/problem/1112 线段树区间操作,每一个线段对应的点包含三个信息: \(l\):表示这个区间最左边的点的数值: \(r\):表示这个区间最右边的点的数值: \(cnt\):表示这个区间有多少个数值段. 合并的时候: 根节点的 \(l\) 值等于左儿子节点的 \(l\) 值: 根节点的 \(r\) 值等于右儿子节点的 \(r\) 值

HDU 1754 I Hate It 线段树

I Hate It Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多组测试,请处理到文件结束.在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目.学生ID编号分别从1编到N.第二行包

HDU 1166 敌兵布阵 线段树

敌兵布阵 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视.中央情

【bzoj4276】[ONTAK2015]Bajtman i Okr?g?y Robin 线段树优化建图+费用流

题目描述 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢走c[i]元.作为保安,你在每一段长度为1的时间内最多只能制止一个强盗,那么你最多可以挽回多少损失呢? 输入 第一行包含一个正整数n(1<=n<=5000),表示强盗的个数. 接下来n行,每行包含三个正整数a[i],b[i],c[i](1<=a[i]<b[i]<=5000,1<=c[i]

【bzoj4184】shallot 线段树+高斯消元动态维护线性基

题目描述 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱从自己手中的小葱苗里选出一些小葱苗使得选出的小葱苗上的数字的异或和最大. 这种小问题对于小葱来说当然不在话下,但是他的身边没有电脑,于是他打电话给同为Oi选手的你,你能帮帮他吗? 你只需要输出最大的异或和即可,若小葱手中没有小葱苗则输出0. 输入 第一行一个正整数n表示总时间:第二行n个整数a1,a2...an,