n<5e5,x<1e9
希望把一些”奖杯”插入到完美二叉树中,一旦一个节点被插入,他的下层不能被插入.优先满足先出现的要求.
首先,想到用二进制来模拟,是容易的,但是遇到问题是这里的最大层数有1e9,所以我们不能用数组来存,用map.
//map这个蛇皮东西,最近几次用它都出问题,好像是一旦用他连pair就不太稳..
那么我们可以很容易模拟一次放入,就是二进制加法,这里我一开始觉得不行,因为似乎是平方级的,但是后来想了一下其实不会的,毕竟不可能一直有那么多连的1给你进.
接下来重要的是,如何判断一个奖杯能不能被插入.这是容易的
当然,两个i+1层进位为一个i层的.
有两种可能.
1.插入这个后,会导致顶点(0层)出现,但是在这一层之下,还有此前被插入过的.
2.0层已经出现了.
第二种是容易判断的.
主要是第一种,首先,判断这一层之下是否还有,可以更新一个mx来判断他是不是此时最下层,但是这样还不够,毕竟要判断此前是否全是1,可是我们不能真的加,下一次遇到时,还要判断,这样就是平方,不行,所以维护一个已被占满的层数,每次判断,是否比已被占满层数小,如果不是,就开始遍历,遍历时更新p.这样就可以了.
(写到这里我跑回去给p的更新方向改了一下,发现然并卵,显然..这当然不会有区别..好蠢..)
#include <iostream>
#include <map>
using namespace std;
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
typedef long long LL;
const int MAXN = 1e5+17;
const int MOD = 1e9+7;
map<int,int > mp;
int main(int argc ,char const *argv[])
{
#ifdef noob
freopen("Input.txt","r",stdin);freopen("Output.txt","w",stdout);
#endif
int n,mx = -1,p=0;
cin>>n;
for (int j = 0; j < n; ++j)
{
int x;
cin>>x;
if(mp[0]==1||x<=p)
{
puts("No");
continue;
}
if(x!=mx)
{
bool skp = true;
for (int i = p+1; i <= x&&skp; ++i)
{
if(mp[i]!=1) skp=false;
else p++;
}
if(skp)
{
puts("No");
continue;
}
}
mp[x]++;
mx = max(x,mx);
while(mp[x]==2&&x>-1)
{
mp[x]=0;
if(mx==x) mx--;
x--;
if(x>-1) mp[x]++;
}
puts("Yes");
}
return 0;
}