专栏文章
题解:CF2062E1 The Game (Easy Version)
CF2062E1题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqdqymm
- 此快照首次捕获于
- 2025/12/04 03:08 3 个月前
- 此快照最后确认于
- 2025/12/04 03:08 3 个月前
[CF2062E1] The Game (Easy Version)
注意到如果对于某个点 ,所有权值比 大的点都在他的子树内,那么删掉 后就无法操作了。因此考虑按权值从大到小扫一遍,如果扫到了 ,说明所有权值比 大的点都是先手必输的,那么如果 并不满足一开始说的那个条件,则删掉 后再操作任意的点都一定是先手必输的,因此输出 即可。条件的判定可以用 实现,复杂度 。
CPP
#include<bits/stdc++.h>
#define ll long long
#define pn putchar('\n')
#define mset(a,x) memset(a,x,sizeof a)
#define mcpy(a,b) memcpy(a,b,sizeof a)
#define all(a) a.begin(),a.end()
#define fls() fflush(stdout)
using namespace std;
int re()
{
int x=0;
bool t=1;
char ch=getchar();
while(ch>'9'||ch<'0')
t=ch=='-'?0:t,ch=getchar();
while(ch>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return t?x:-x;
}
const int maxn=4e5+5;
void gx(int &x,int y)
{
x=max(x,y);
}
void gn(int &x,int y)
{
x=min(x,y);
}
int n,idx;
int id[maxn],rid[maxn];
vector<int>a[maxn];
vector<int>e[maxn];
int tree[maxn];
void add(int x,int ad)
{
for(int i=x;i<=n;i+=i&-i)
tree[i]+=ad;
}
int qry(int x)
{
int ret=0;
for(int i=x;i;i-=i&-i)
ret+=tree[i];
return ret;
}
int qry(int l,int r)
{
return qry(r)-qry(l-1);
}
void dfs(int pos,int fa)
{
id[pos]=++idx;
for(int v:e[pos])
{
if(v==fa)
continue;
dfs(v,pos);
}
rid[pos]=idx;
}
void solve()
{
n=re();
for(int i=1;i<=n;i++)
{
tree[i]=0;
a[i].clear();
e[i].clear();
}
int mx=0;
for(int i=1;i<=n;i++)
{
int x=re();
gx(mx,x);
a[x].push_back(i);
}
for(int i=1;i<n;i++)
{
int u=re(),v=re();
e[u].push_back(v);
e[v].push_back(u);
}
idx=0;
dfs(1,0);
int cnt=0;
for(int i:a[mx])
{
cnt++;
add(id[i],1);
}
for(int i=mx-1;i;i--)
{
for(int j:a[i])
{
if(qry(id[j],rid[j])<cnt)
{
printf("%d\n",j);
return;
}
}
for(int j:a[i])
{
cnt++;
add(id[j],1);
}
}
puts("0");
}
signed main()
{
int T=re();
while(T--)
solve();
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...