用线段树方式建树 [ 0, n]
已知[ l, r] 结点 求n
若 建一个[0, 2*r] 的线段树 这是的总点数的奇的,(左子树!=右子树
[0, r] 在左子树里 则n最大为2*r
若 建一个[0, 2*r+1] 的线段树 (左子树==右子树
[0, r] 在左子树里 这时则 [0, r] 就可以建树
所以搜的时候超出2*r 就直接return
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #define cler(arr, val) memset(arr, val, sizeof(arr)) #define FOR(i,a,b) for(int i=a;i<=b;i++) #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 101000; const int MAXM = 200000; const int INF = 0x3f3f3f3f; const int mod = 1000000007; const double eps= 1e-8; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 LL ans,flag,L,R; void dfs(LL l,LL r) { if(r>2*R||flag&&r>=ans) return ; if(l==0) { flag=1; ans=r; return ; } LL len=r-l+1; if(l-len-1>=0) dfs(l-len-1,r); if(l-len>=0) dfs(l-len,r); dfs(l,r+len-1); dfs(l,r+len); } int main() { while(scanf("%I64d%I64d",&L,&R)!=EOF) { ans=INF;flag=0; dfs(L,R); if(ans==INF) puts("-1"); else printf("%I64d\n",ans); } return 0; } /* */
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-12-17 18:13:23