[dfs] Jzoj P4208 线段树什么的最讨厌了
题解
- 题目大意:给定一个区间问,在满足右区间<=lim的情况下,包含该区间的线段树的最小左右区间为多少
- 那么可以考虑一下,我们打线段树的时候,二分一个mid,然后分两部分走
- 这样我们考虑反着往上推,那就会出现四种情况
- ①上一个区间的[l,r]可以整除2,然后当前走的是左区间
- ②上一个区间的[l,r]可以整除2,然后当前走的是右区间
- ③上一个区间的[l,r]不可以整除2,然后当前走的是左区间
- ④上一个区间的[l,r]不可以整除2,然后当前走的是右区间
- 推到l==0的时候就是ans,取最小值就好了
- 注意特判一些坑爹的地方
代码
1 #include<iostream> 2 #include<cstdio> 3 #define ll long long 4 using namespace std; 5 const ll N=0x7fffffff; 6 ll ans=0,m,L,R,lim; 7 void dfs(ll l,ll r) 8 { 9 if (r>lim||r>ans&&ans!=-1||l<0) return; 10 if (l==0) { if (ans==-1||ans>r) ans=r; return; } 11 if (2*l<r)return; 12 if (l<2*r-l) dfs(l,2*r-l); 13 if (l<2*r-l+1) dfs(l,2*r-l+1); 14 if (r>2*l-r-2) dfs(2*l-r-2,r); 15 if (r>2*l-r-1) dfs(2*l-r-1,r); 16 } 17 int main() 18 { 19 cin>>m; 20 for (ll i=1;i<=m;i++) 21 { 22 cin>>L>>R>>lim,ans=-1,dfs(L,R); 23 cout<<ans<<endl; 24 } 25 return 0; 26 }