7.16_D题

题目链接:http://code.bupt.edu.cn/problem/p/427/

一个很单纯的every-sg模型

代码:

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#define N 100010
using namespace std;
int step[N];
int sg[N];
int stone[N];
vector<int> g[N];
 
int mex(int a)
{
    if(g[a].empty()) return 0;
    if(sg[a]!=-1)
        return sg[a];
    int test=0;
    for(int i=0;i<g[a].size();i++)
    {
        if(sg[g[a][i]]==0)
            test=1;
        else if(sg[g[a][i]]==-1)
            return mex(g[a][i]);
    }
    return test;
}
int find_step(int a)
{
    if(g[a].empty()) return 0;
    if(step[a]!=-1) return step[a];
    int ma=0,mi=999999;
    for(int i=0;i<g[a].size();i++)
    {
        if(sg[a]==1)
        {
            if(!sg[g[a][i]])
                ma=max(ma,find_step(g[a][i]));
        }
        else
        {
            if(sg[g[a][i]])
                mi=min(mi,find_step(g[a][i]));
        }
    }
    if(sg[a])
        return ma+1;
    else
        return mi+1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(step,-1,sizeof(step));
        memset(sg,-1,sizeof(sg));
        for(int i=0;i<N;i++)
            g[i].clear();
        int n,m;
        int num;
        scanf("%d%d",&n,&m);
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&num);
            g[num].push_back(i);
        }
        for(int i=0;i<m;i++)
            scanf("%d",&stone[i]);
        for(int i=n;i>=1;i--)
        {
            sg[i]=mex(i);
            //cout<<sg[i]<<endl;
        }
        for(int i=1;i<=n;i++)
        {
            step[i]=find_step(i);
            //cout<<step[i]<<endl;
        }
        int ans=0;
        for(int i=0;i<m;i++)
        {
            ans=max(ans,step[stone[i]]);
        }
        if(ans%2)
            printf("MengMengDa!\n");
        else
            printf("So sad...\n");
    }
    return 0;
}


你可能感兴趣的:(ACM,博弈)