题解 P6776 【[NOI2020]超现实树】
学文化课之前分享一下自己的方法和代码留作纪念。
我们需要求
说一下为了方便而下的定义:
-
-
- 如果
\ grow(T,i) 仅有有限棵树不在其中,那么久称\ grow(T,i) 是几乎完备的。
我们考虑已知
解法
我们设左右儿子分别为
设
设
设
设
定理
证明: 第一种情况非常显然,我们只考虑第二种情况。
我们注意到
前两种情况分别对应
充分性:如果命题成立,一棵有左右儿子的树不在
必要性:如果
证毕。
由于
由于洛谷没有数据,代码仅在loj上AC。
#include<bits/stdc++.h>
using namespace std;
int ttt,m,n[2002002];
vector<pair<int,int> > ss[2002002];
vector<pair<int,int> > tr[2002002];
int tot=0;
inline bool isleaf(int x,int y)
{
return (tr[y][x].first==0)&&(tr[y][x].second==0);
}
inline int lson(int x,int y)
{
return tr[y][x].first;
}
inline int rson(int x,int y)
{
return tr[y][x].second;
}
inline bool dfs(int u)
{
if(ss[u].empty()) return 0;
int i=0;
while(i<(int)ss[u].size())
{
int x=ss[u][i].first,y=ss[u][i].second;
if(isleaf(x,y)) return 1;
++i;
}
int lss,rss,llrs,rlrs;
++tot;
lss=tot;
++tot;
rss=tot;
++tot;
llrs=tot;
++tot;
rlrs=tot;
i=0;
while(i<(int)ss[u].size())
{
int x=ss[u][i].first,y=ss[u][i].second;
if((lson(x,y))&&(!rson(x,y))) ss[lss].push_back(make_pair(lson(x,y),y));
else if((!lson(x,y))&&(rson(x,y))) ss[rss].push_back(make_pair(rson(x,y),y));
else
{
if(isleaf(lson(x,y),y)) ss[llrs].push_back(make_pair(rson(x,y),y));
if(isleaf(rson(x,y),y)) ss[rlrs].push_back(make_pair(lson(x,y),y));
}
++i;
}
if((dfs(lss))&&(dfs(rss))&&(dfs(llrs))&&(dfs(rlrs))) return 1;
return 0;
}
int main()
{
freopen("surreal.in","r",stdin);
freopen("surreal.out","w",stdout);
scanf("%d",&ttt);
while(ttt--)
{
scanf("%d",&m);
int i=1,j=1;
while(i<=m)
{
tr[i].clear();
tr[i].push_back(make_pair(0,0));
scanf("%d",&n[i]);
j=1;
while(j<=n[i])
{
int l,r;
scanf("%d%d",&l,&r);
tr[i].push_back(make_pair(l,r));
++j;
}
++i;
}
i=1;
while(i<=tot)
{
ss[i].clear();
++i;
}
tot=0;
++tot;
i=1;
while(i<=m)
{
ss[tot].push_back(make_pair(1,i));
++i;
}
if(dfs(tot)) printf("Almost Complete\n");
else printf("No\n");
}
return 0;
}