线段树什么的最讨厌了

题意

T 组数据。
每组数据给你一个区间 [l,r] lim ,求一个最小的 n ,使该区间为 0 ~ n 的线段树的一个节点代表的区间,且 nlim
线段树一个 [L,R](LR) 的节点的叶节点代表的区间为 [L,mid],[mid+1,R](mid=L+R2)

lim2109
0lr109
T100
lrl+12103

Time Limits:1000ms
Memory Limits:512M

分析

DFS
枚举当前节点的父亲节点代表的区间(最多只有4种情况),加上一些简单的剪枝。因为每次都会使 lrl+1 变为原来的 12 ,所以复杂度是 O(4loglrl+1) ,即 (lrl+1)2

代码

#include <cstdio>

const int N = 2e9 + 10;
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 --) {
        scanf("%d%d%d",&L,&R,&lim);
        ans = N;
        dfs(L,R);
        if (ans == N) printf("-1\n");
        else printf("%d\n",ans);
    }
}

你可能感兴趣的:(线段树什么的最讨厌了)