CF-456D-(字典树+树上dp+博弈)
题意:http://codeforces.com/problemset/problem/456/D
两个人玩游戏。游戏是拼单词,给出了一个含有n个单词的词库。当前单词初始为空,每个人轮流给它末尾加一个字母,要求当前单词是词库中任意一个词的前缀,当某个人不能加字母了他就输。这个游戏重复k局,一局输的人下一局先手,最后一局定胜负。两个人都不蠢,求第一局先手是否能保证最后能赢,能就输出First,不能则输出Second。
思路:
应该要想到字典树,我一开始想到ac自动机(真是够了,哪有这么难)
博弈的话dp一下先确定一局里先手能否控制自己的输赢状态
最后再对k讨论一下就行了
1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0); 2 #include <cstdio>//sprintf islower isupper 3 #include <cstdlib>//malloc exit strcat itoa system("cls") 4 #include <iostream>//pair 5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin); 6 #include <bitset> 7 //#include <map> 8 //#include<unordered_map> 9 #include <vector> 10 #include <stack> 11 #include <set> 12 #include <string.h>//strstr substr strcat 13 #include <string> 14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9; 15 #include <cmath> 16 #include <deque> 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less 18 #include <vector>//emplace_back 19 //#include <math.h> 20 #include <cassert> 21 #include <iomanip> 22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor 23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare) 24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation 25 //****************** 26 clock_t __START,__END; 27 double __TOTALTIME; 28 void _MS(){__START=clock();} 29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;} 30 //*********************** 31 #define rint register int 32 #define fo(a,b,c) for(rint a=b;a<=c;++a) 33 #define fr(a,b,c) for(rint a=b;a>=c;--a) 34 #define mem(a,b) memset(a,b,sizeof(a)) 35 #define pr printf 36 #define sc scanf 37 #define ls rt<<1 38 #define rs rt<<1|1 39 typedef pair<int,int> PII; 40 typedef vector<int> VI; 41 typedef unsigned long long ull; 42 typedef long long ll; 43 typedef double db; 44 const db E=2.718281828; 45 const db PI=acos(-1.0); 46 const ll INF=(1LL<<60); 47 const int inf=(1<<30); 48 const db ESP=1e-9; 49 const int mod=(int)1e9+7; 50 const int N=(int)1e5+10; 51 52 int trie[N][26],tot; 53 54 void insert(char s[]) 55 { 56 int len=strlen(s); 57 int root=0; 58 for(int i=0;i<len;i++) 59 { 60 int id=s[i]-'a'; 61 if(!trie[root][id]) trie[root][id]=++tot; 62 root=trie[root][id]; 63 } 64 } 65 66 char s[N]; 67 int dp[N][2]; 68 void dfs(int root,int c) 69 { 70 bool ok=0,no=0; 71 bool ok2=1,no2=1; 72 bool have=0; 73 for(int i=0;i<=25;++i) 74 { 75 int to=trie[root][i]; 76 if(to) 77 { 78 have=1; 79 dfs(to,c+1); 80 if(dp[to][1])ok=1; 81 if(dp[to][0])no=1; 82 if(!dp[to][1])ok2=0; 83 if(!dp[to][0])no2=0; 84 } 85 } 86 if(!have) 87 { 88 if(c&1)dp[root][1]=1; 89 else dp[root][0]=1; 90 return ; 91 } 92 if(c&1) 93 { 94 if(ok2&&no2) 95 { 96 dp[root][0]=0; 97 dp[root][1]=0; 98 } 99 else if(no2) 100 { 101 dp[root][0]=1; 102 dp[root][1]=0; 103 } 104 else if(ok2) 105 { 106 dp[root][0]=0; 107 dp[root][1]=1; 108 } 109 } 110 else 111 { 112 if(ok&&no) 113 { 114 dp[root][0]=1; 115 dp[root][1]=1; 116 } 117 else if(no) 118 { 119 dp[root][0]=1; 120 dp[root][1]=0; 121 } 122 else if(ok) 123 { 124 dp[root][0]=0; 125 dp[root][1]=1; 126 } 127 } 128 } 129 130 int main() 131 { 132 int n,k; 133 sc("%d%d",&n,&k); 134 for(int i=1;i<=n;++i) 135 { 136 sc("%s",s); 137 insert(s); 138 } 139 dfs(0,0); 140 bool ok=0,no=0; 141 for(int i=0;i<=25;++i) 142 { 143 int to=trie[0][i]; 144 if(to) 145 { 146 if(dp[to][1])ok=1; 147 if(dp[to][0])no=1; 148 } 149 } 150 bool ans=0; 151 if(ok&&no) 152 { 153 ans=1; 154 } 155 else if(ok) 156 { 157 if(k&1)ans=1; 158 } 159 if(ans) 160 pr("First\n"); 161 else 162 pr("Second\n"); 163 return 0; 164 } 165 166 /**************************************************************************************/