2023NOIP A层联测31 T4 民主投票
2023NOIP A层联测31 T4 民主投票
思维好题。
思路
首先可以设
如果一个点的票数超过
设
如果
可以二分求这个最小的
点
如果
对于
此时求
如果
如果
CODE
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
struct node
{
int to,nxt;
}edge[maxn];
int n,tot=0;
int head[maxn],f[maxn],sz[maxn],ans[maxn];
bool fg;
inline void add(int x,int y)
{
tot++;
edge[tot].to=y;
edge[tot].nxt=head[x];
head[x]=tot;
}
inline void clr()
{
tot=0;
for(int i=0;i<=n;i++) head[i]=0,edge[i]={0,0};
}
inline void dfs_sz(int u)
{
sz[u]=1;
for(int i=head[u];i;i=edge[i].nxt) dfs_sz(edge[i].to),sz[u]+=sz[edge[i].to];
}
inline void dfs_ans(int u,int mid)
{
f[u]=0;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
dfs_ans(v,mid);
f[u]+=f[v]+1;
if(u==1&&f[u]-mid>0&&fg) return ;
}
f[u]=max(0,f[u]-mid);
}
inline void dfs_change(int u,int mid)
{
if(sz[u]-1==mid){ans[u]=1;return;}
for(int i=head[u];i;i=edge[i].nxt) if(f[edge[i].to]>0) dfs_change(edge[i].to,mid);
}
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
fg=1;
scanf("%d",&n);
clr();
for(int i=2;i<=n;i++)
{
int x;
scanf("%d",&x);
add(x,i);
}
dfs_sz(1);
int l=1,r=n,x=0;
while(l<=r)
{
int mid=(l+r)>>1;
dfs_ans(1,mid);
if(f[1]==0) r=mid-1,x=mid;
else l=mid+1;
}
for(int i=1;i<=n;i++) {ans[i]=(sz[i]-1>x);}
fg=0;
dfs_ans(1,x-1);
if(f[1]==1) dfs_change(1,x);
for(int i=1;i<=n;i++) printf("%d",ans[i]);
putchar('\n');
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现