• 线段树什么的最讨厌了


    Description

    小Y 最近学习了线段树,但是由于她的智商比较低,运用的还不是很熟练。于是小R 给了她一点练习题训练,其中有一道是这样的。
    这是小R 写的线段树的一段建树代码:
    在这里插入图片描述
    只要调用buildtree(1,0,n) 就可以得到一颗线段树了。显然,一颗线段树一共有O(n) 个节点,因为每一个节点都代表了一个不同的区间,所以线段树上一共出现了O(n) 个不同的区间。
    现在小R 给了你一个区间[l; r],他想要你告诉他一个最小的n 使得区间[l; r] 出现在了用buildtree(1,0,n) 建出来的线段树中。

    Input

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

    Output

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

    Sample Input

    2
    0 5 10
    6 7 10

    Sample Output

    5
    7

    Data Constraint
    在这里插入图片描述

    .
    .
    .
    .
    .
    分析
    我们可以从该区间逆向推它的父节点
    以该区间为左子树或为右子树

    共有四种情况:
    q=y-x+1;
    dfs(x-q,y);
    dfs(x-q-1,y);
    dfs(x,y+q-1);
    dfs(x,y+q);

    一定注意剪枝,没做好可能会直接爆蛋

    .
    .
    .
    .
    .
    程序:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    long long l,r,lim;
    long long minn;
    
    void dfs(long long x,long long y)
    {
    	if (y>lim) return;
    	if (y>=minn) return;
    	if (x==0)
    	{
    		minn=y;
    		return;
    	}
    	long long q=y-x+1;
    	if (x-q==0||x-q>=q+q) dfs(x-q,y);
        if (x-q==1||x-q-1>=q+q+1) dfs(x-q-1,y);
        if (x>=q+q-1) dfs(x,y+q-1);
        if (x>q+q) dfs(x,y+q);
    }
    
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while (t--)
    	{
    		scanf("%lld%lld%lld",&l,&r,&lim);
    		if (r>lim)
    		{
    			printf("-1
    ");
    			continue;
    		}
    		if (l>r)
    		{
    			printf("-1
    ");
    			continue;
    		}
    		minn=2147483647;
    		dfs(l,r);
    		if (minn!=2147483647)
    		{
    			if (minn<=lim) printf("%lld
    ",minn); else printf("-1
    ");
    		} else printf("-1
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    css引入方式
    HTML标签
    动态导入模块impoerlib
    pymysql连接数据库
    创建数据库表之引擎
    IO多路复用互动聊天,select函数监听
    欧拉筛法求素数个数
    与三角形相关的问题 WITH 有向面积
    时间复杂度的计算
    折半查找
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/10458953.html
Copyright © 2020-2023  润新知