转载请注明出处谢谢:blog.csdn.net/vmurder/article/details/42968425
诶那个什么94.net这篇题解你要是转载别删出处了谢谢。。。
我再处理一下嘿嘿。blog。csdn。net|vmurder|article|details|42968425
。是.
|是/
做个实验:看看它的转载机制会不会把代码都删除
#include <cstdio> using namespace std; int main() { puts("blog.csdn.net/vmurder/article/details/42968425"); }
嗯,这是一道原创题。
然后下面贴的是我当时写的题解。
本来以为在BZOJ上面晒一段时间可以有人去花时间想一想这道题。
但是貌似我想多了。。。
{
这道题显然是一道博弈题,然后因为环断了一个点,所以不妨先把它处理成一条链。这道题我对于数据规定了一种性质:任意两条边不相交。这样就大有可做了。
首先我们思考,从起点出发,那么因为每到一个点,之前的点就都走过了,所以现在无法通过边回头,那么也就是说,当总点数(别忘了刨去那一个断点)是奇数的时候,直接从1出发,就可以保证必胜。
那么总点数是偶数怎么办呢?好说,我们直接从第二个点出发就行了,真的行么?这个时候却会出现一个问题,就是往前走,可能有某个点可以回到1,这样先手就输了,所以想得这么简单是不行的。
这道题限定了边不“交叉”,所以链一定可以被划分成若干个(可以只有1个)独立的区间,而我们从每个区间的开头出发,就不可能再回到之前的节点。
而我们如果从一段区间的中间出发,那么我们至多沿着某边回溯一次,然后就需要一直往前走,而开始节点的前一个节点,则是一个必胜节点。
这个时候我们进行讨论:(节点总数为偶,不然直接出解)
---------------------------------------------------
一、从奇点出发,先手可以选择在偶点回溯,如果此偶点可以回到偶点,即胜。而我们还需要保证在奇点对方无法回到偶点。
二、从偶点出发,先手可以选择在奇点回溯,如果此奇点可以回到奇点,即胜。而我们还需要保证在偶点对方无法回到奇点。
--------------------------------------------------
注意到上面两种情况,从奇点出发则必须回溯,而偶点则不然。所以我们可以特判一个区间的结束节点:
如果结束节点是偶,且不能回到奇点,那么必胜。
如果结束节点是奇,那我们不可以在结束节点开始,否则对方只需要往前一步,我们就输了,且无法逆转。
特判了结束节点以后,我们可以发现,如果我们可以在某个节点回溯,并且取得胜利,那么从开始节点到这个节点这一段区间,对方是不可以有逆转的机会的(奇点回偶/偶点回奇),这样我们不妨把开始节点无限右推,推到回溯节点前一位。
然后对于每段区间,我们只需要枚举回溯节点,然后check一下它的上一个节点是否可以逆转,就可以出解了。
显然这样扫一遍,发现所有的节点都是必败,那么这场博弈就输了,这样就只能输出“污得不行”了。
细节:我们记录了每个点能否回溯到奇/偶点,但是有可能能回溯,check却已经被堵?不可能。
因为奇需要回到奇,而我们是从它前一个点(偶)开始的,而偶则亦然。
话说这道题可以记忆化深搜水过么?如果可以,那么思路应该是只需要判断某个节点如果是一段区间的开始节点,那么它就只能往前走,不能回头,故它是一个结束节点,然后就可以记忆化进行推演了。
但是这道题中,一个节点并不是有出边就可以走的,,而状态压缩,更是活在梦里,随意YY了一下,感觉并不能这么水过。
我又想了一下,发现记忆化搜索的话你不知道那些点能走,哪些点不能,比如偶环套偶环,外面的偶环你倒是可以直接根据奇偶性判断胜负,里面的环呢?233。不需要卡!因为它本身就没法搜!要记忆化,只能先枚举开始点,(这样貌似依然不可行),然后再搜,即使可行,也是n^2的,显然TLE 了。。。
}
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1001000 using namespace std; int n,m,vv[N],cnt; bool jd[N][2]; void build_chain() { int a,b,c; scanf("%d%d%d",&n,&m,&c); for(int i=1;i<n;i++)vv[i]=i; while(m--) { scanf("%d%d",&a,&b); if(a==b||a==c||b==c)continue; a=(a+n-c)%n,b=(b+n-c)%n; if(a<b) { vv[a]=max(vv[a],b); jd[b][a&1]=1; } else { vv[b]=max(vv[b],a); jd[a][b&1]=1; } } n--; } int l[N],r[N]; bool build_district() { for(int i=1;i<=n;i++) { cnt++; if(vv[i]==i)return 1; l[cnt]=i; r[cnt]=i=vv[i]; } return 0; } bool check(int f) { if((r[f]&1)==0&&jd[r[f]][1]==0)return 1; for(int i=l[f]+1;i<=r[f];i++) { if((i&1)&&jd[i][1]) if(jd[i-1][1]==false)return 1; if((i%2==0)&&jd[i][0]) if(jd[i-1][0]==false)return 1; } return 0; } int main() { build_chain(); if(!n) { puts("galaxy"); return 0; } if((n&1)||build_district()==1) { puts("dawn"); return 0; } for(int i=1;i<=cnt;i++) { if(check(i)) { puts("dawn"); return 0; } } puts("galaxy"); return 0; }
【BZOJ3880】炼辰 有向有环有限制的博弈 我是出题人!
原文地址:http://blog.csdn.net/vmurder/article/details/42968425