[XSY 1149][sg函数]游戏

题意
Description
现在有两个人在一个V个结点的有向图上玩一个双人游戏,图上的点被编号为0到V-1,保证图中无环和自圈。游戏的规则如下:
1.初始的时候i号点有一个正权值value_i
2.两名玩家依次操作,每个玩家在当前回合可以选择一个具有如下性质的点
-该点的权值为正
-该点具有至少一条出边
如果不存在这样子的点,那么当前回合的玩家输掉整局游戏
3.当某名玩家选定一个点以后,将该点的value减一,并将Ki个该点可以到达的点的value加一,这Ki个点由当前玩家选择,并允许选择重复的点(若被选择的点value扣完后非负)
现在给出整个有向图和初始权值,你的任务是判断先手玩家是否存在必胜策略。

Input
输入包括多组数据。第一行一个整数T表示数据组数。每一组数据第一行为两个整数V和E。其中,V表示顶点的数目,E表示边的数目。以下的E行,每行两个整数u,v,表示存在一条u到v的边,数据保证每个点至多存在17条出边。接下来的一行包含V个整数K0,K1,…,KV-1,每个点的K值在0到100之间。再接下来的一行包括一个整数R表示在这一张图上进行的游戏的轮数。最后的R行,每行V个整数Value_0,Value_1,…,Value_V-1,表示每一轮的初始value,这些value值都在0到100之间。

Output
对于每一组数据输出R+1行,第一行为Game#i:,表示第几局游戏,游戏从1开始编号。接下来R行,每一行为Round#j: result,j为当前游戏的轮数,result为一个字符串WINNING或者LOSING表示先手的胜败态,你可以认为两个人都采取最优策略。在每局游戏之后打印一个空行,具体输出细节参见样例。

Sample Input
2
3 3
1 0
2 0
1 2
0 2 2
5
3 0 0
4 1 0
5 0 1
1 1 1
2 2 2
4 3
0 1
1 2
2 3
3 2 1 0
5
0 0 0 0
0 0 0 1
0 0 1 0
0 1 0 0
1 0 0 0
Sample Output
Game#1:
Round#1: LOSING
Round#2: WINNING
Round#3: WINNING
Round#4: WINNING
Round#5: LOSING

Game#2:
Round#1: LOSING
Round#2: LOSING
Round#3: WINNING
Round#4: WINNING
Round#5: LOSING
HINT
对于20%的数据:v<=5。
对于100%的数据:T<=20,V<=100,E<=1500。

把每个点上的权值v当成v个子游戏。最后我们用sg定理合并即可。
如何求出一个点上的子游戏的sg值?
注意到一个点的后继状态很少,枚举再求个mex即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
#define V 105
#define E 1505
int bitscount[200010];
int head[V],v[E],nxt[E],out[V],in[V],tot=0;
bool vis[V];
int K[V];
int sg[V];
bool ap[200010];
int sum[200010];
int num[200010];
int lowbit(int x){return x&(-x);}
void solve(int u){
    vis[u]=true;
    for(int i=head[u];i;i=nxt[i])
        if(!vis[v[i]])solve(v[i]);
    if(!out[u])sg[u]=0;
    else{
        sum[0]=0;
        for(int i=head[u],t=0;i;i=nxt[i],++t)num[1<<t]=sg[v[i]];
        for(int i=1;i<(1<<out[u]);++i)
            sum[i]=num[lowbit(i)]^sum[i-lowbit(i)];
        for(int i=0;i<(1<<out[u]);++i)
            if(K[u]>=bitscount[i]&&(K[u]-bitscount[i])%2==0)ap[sum[i]]=true;
        int Ans=0;
        while(ap[Ans])Ans++;
        sg[u]=Ans;
        for(int i=0;i<(1<<out[u]);++i)
            if(K[u]>=bitscount[i]&&(K[u]-bitscount[i])%2==0)ap[sum[i]]=false;
    }
}
int main(){
    for(register int i=0;i<(1<<17);++i)bitscount[i]=bitscount[i>>1]+(i&1);
    int T;
    scanf("%d",&T);
    for(register int tt=1;tt<=T;++tt){
        printf("Game#%d:\n",tt);
        memset(head,0,sizeof(head));tot=0;
        memset(out,0,sizeof(out));
        memset(in,0,sizeof(in));
        memset(vis,false,sizeof(vis));
        scanf("%d%d",&n,&m);
        int s,e;
        for(register int  i=1;i<=m;++i){
            scanf("%d%d",&s,&e);
            s++;e++;
            tot++;v[tot]=e;nxt[tot]=head[s];head[s]=tot;
            out[s]++;in[e]++;
        }
        for(register int i=1;i<=n;++i)scanf("%d",&K[i]);
        for(register int i=1;i<=n;++i)
            if(!in[i])solve(i);
        int R;
        scanf("%d",&R);
        for(register int t=1;t<=R;++t){
            int x;
            int Zjr=0;
            for(register int i=1;i<=n;++i){
                scanf("%d",&x);
                if(x&1)Zjr^=sg[i];
            }
            if(Zjr)printf("Round#%d: WINNING\n",t);
            else printf("Round#%d: LOSING\n",t);
        }
        puts("");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值