题解:CF2062E1 The Game (Easy Version)

· · 题解

[CF2062E1] The Game (Easy Version)

注意到如果对于某个点 x ,所有权值比 x 大的点都在他的子树内,那么删掉 x 后就无法操作了。因此考虑按权值从大到小扫一遍,如果扫到了 x ,说明所有权值比 x 大的点都是先手必输的,那么如果 x 并不满足一开始说的那个条件,则删掉 x 后再操作任意的点都一定是先手必输的,因此输出 x 即可。条件的判定可以用 \rm BIT 实现,复杂度 O(n \log n)

#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;
}