专栏文章

题解: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)

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

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 条评论,欢迎与作者交流。

正在加载评论...