Gym 101158G Placing Medals on a Binary Tree

题意:有一颗无穷大的满二叉树,每一次我们向树上的某一层的某个节点放置奖牌,奖牌排斥的条件为:从该节点到根的路径上无其他奖牌,如果能放置则放置,否则不放跳过,并且要按照输入的顺序放置,每次输出Yes或者No


题解:先找到最大的深度K,那么说明如果全部放置在第K层,那么会占据一个结点,如果是K-1层则会占据2个结点,所以把问题转化为了一共有2的K次方的点可以放,把放在X层的点转化到K层,也就是占据2的K-X次方的点,所以每次只会加上一个2的K-X次方,如果加上之后大于了2的K次,则说明不能放,则减去,否则可以放。

相当于是一个简单的2进制的加法和减法,每次在一位上加1,如果不能放则减去1抵消加上的1。因为最大的层数是10的9次,所以用map来实现这个模拟;但是还需要一些优化,如果现在最多放2的K次,当前放了2的K-1次,那么就可以把K变成K-1,删除那个K-1次位上的1,意思就是如果现在最高位已经是1了,那么就可以不用考虑这一位,超过一半被使用,那么就可以只考虑剩下的一半,把容量减半


代码:

#include<bits/stdc++.h>
#define N 500005
#define P pair<int,int>
using namespace std;
typedef long long ll;
const int M=1e9+7;
const int inf=1e9+7;
int a[N];
map<int,int>mp;
void add(int x)
{
    mp[x]++;
    while(mp[x]==2){
        mp[x+1]++;
        mp[x++]=0;
        mp.erase(x-1);
    }
}
void sub(int x)
{
    int y=x;
    while(!mp[y]){
        mp[y++]=1;
    }
    mp[y]=0;
    mp.erase(y);
}
int main()
{
    int n,tot=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        tot=max(tot,a[i]);
    }
    map<int,int>::iterator it;
    int num=tot;
    for(int i=0;i<n;i++){
        int x=tot-a[i];
        if(x>num||x==num&&mp.size()){
            printf("No\n");
            continue;
        }
        add(x);
        it=mp.end();
        it--;
        if(it->first>num||(it->first==num&&mp.size()>1)){
            printf("No\n");
            sub(x);
        }
        printf("Yes\n");
        if(x==num){
            num=-1;
            mp.clear();
        }
        while(!mp.empty()){
            it=mp.end();
            it--;
            if(it->first>num)mp.erase(it);
            else if(it->first==num-1){
                num--;
                mp.erase(it);
            }
            else break;
        }
    }
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值