2019 icpc Nanchang tournament G Winner

Topic links: https://nanti.jisuanke.com/t/40259

 

Ichuan really likes to play games, so he organized a game competition with NN participating players.

Follows are the rule of the game competition.

  1. There are three modes in the game, in each mode, players have different ability values, in addition, each player may have different ability value in different mode.

  2. There are a total of N-1 matches. In each match, two players who have not yet been eliminated will play against each other in one of the modes. The player who has high ability in this mode will win, and the other one will be eliminated.

  3. The only player who remains in the game after all N-1 matches will be the winner.

As the organizer of the game, ichuan can manipulate the result of the game. Namely, for each match, he can choose both players and match mode. Of course, he can only choose players who have not yet been eliminated.

Ichuan has some friends, some of them will ask him: "Does player XX will be the winner?" Answering this question will give you a lot of reward, so you need to write a program which can answer these questions.

Input

The first line contains integers N and Q(1N,Q105), the number of players and the number of requests.

The next three lines, each line contains N integers, the Xth integer Y(1Y106)represents the ability value of player X in this mode.,

The next qq lines, each line only has one integer X(1Xn), which means ichuan's friend wants to know if player X can be the winner.

Output

For each query, if player X has a chance to be the winner, output "YES", otherwise output "NO"

Extra spaces at the end of each row, the answer does not affect the validity of the output

Sample input

4 4 
1 2 3 4
1 2 4 3
2 1 3 4
1 
2 
3
4

Sample Output

NO 
NO 
YES 
YES    

next players is n, there are three game modes, each mode has a strength value of each player, the higher strength values can defeat lower of the referee can choose two players in any mode: the meaning of problems competition, high strength wins, the elimination of low strength, q an inquiry and asked the referee if i can help players win in experience n-1 field .

Ideas: three modes, in each mode, according to the strength of the sort, then adjacent high strength and low strength are connected by edges, shrink point, the point of zero strongly connected components are possible win points.

Code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int maxm=1e6+10;
struct node{
    int u,v,w,nxt;
}e[maxm];
int h[maxn],low[maxn],dfn[maxn],vis[maxn];
int st[maxn],belong[maxn],du[maxn];
int n,q,cnt,tot,top,num,y;
struct nd{
    int x,id;
}a[maxn];
bool cmp(nd a1,nd a2)
{
    return a1.x<a2.x; 
}
void init()
{
    memset(h,-1,sizeof(h));
    memset(belong,0,sizeof(belong));
    memset(du,0,sizeof(du));
    memset(dfn,0,sizeof(dfn));
    memset(vis,0,sizeof(vis));
    cnt=tot=num=top=0;
}

void add(int u,int v)
{
    e[cnt].u=u,e[cnt].v=v;
    e[cnt].nxt=h[u];h[u]=cnt++;
}

void tarjan(int u)//缩点 
{
    dfn[u]=low[u]=++tot;
    vis[u]=1;
    st[++top]=u;
    for(int i=h[u];i!=-1;i=e[i].nxt)
    {
        int v=e[i].v;
        if(!dfn[v]) 
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);    
        }
        else if(vis[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        int t;
        num++;
        do{
            t=st[top--];
            vis[t]=0;
            belong[t]=num;
        }while(t!=u);
    }
}

int main()
{
    init();
    scanf("%d%d",&n,&q);
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&a[j].x);
            a[j].id=j;
        }
        sort(a+1,a+n+1,cmp);//排序 
        for(int j=1;j<n;j++)//连边 
            add(a[j+1].id,a[j].id);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            tarjan(i);
    for(int i=0;i<cnt;i++)//计算入度 
        if(belong[e[i].u]!=belong[e[i].v])
            du[belong[e[i].v]]++;
    for(int i=1;i<=q;i++)
    {
        scanf("%d",&y);
        if(du[belong[y]]==0)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/xiongtao/p/11248278.html