loj #6377. 「是男人就过8题——Pony.ai」AStringGame

最近 Alice 和 Bob 在玩一个和字符串有关的游戏。在游戏开始之前,他们会准备 $n$ 个字符串 $s_1, s_2 \ldots s_n$​​ 和一个模板串 $t$, 保证这 $n$ 个字符串都是 $t$ 的子串。

游戏开始后,他们会轮流地执行以下操作,由 Alice 先手。

从 $n$ 个字符串中选择一个字符串 $s_i$​​;

在 $s_i$​​ 末尾增加一个字符;

得到的新字符串需要是 $t$ 的子串;

如果上述过程无法完成,当前玩家失败,假设 Alice 和 Bob 都以最优策略行动,求出谁是游戏的胜者。

本来以为是道神题……读了一遍题后发现是个板子题……

添加字符的操作相当于在 sam 上走一个节点,走不到节点的话就是输了

sam 是一个 DAG,因此在 DAG 上计算一下 SG 函数就行了

所有的查询子串的 SG 函数的异或和如果为正数,那么 Alice 获胜,否则 Bob 获胜

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 2e5 + 10;
 4 int ch[N][26], len[N], pre[N], tot, last, n, sg[N], tmp[N]; char s[N]; bool vis[N];
 5 inline int nd(int l) { return len[++ tot] = l, memset(ch[tot], vis[tot] = 0, sizeof ch[tot]), tot; }
 6 inline void ins(int c) {
 7     int p, np, q, nq;
 8     pre[last = np = nd(len[p = last] + 1)] = 1;
 9     while(p && !ch[p][c]) ch[p][c] = np, p = pre[p];
10     if(p) {
11         pre[np] = q = ch[p][c];
12         if(len[p] + 1 != len[q]) {
13             pre[nq = nd(len[p] + 1)] = pre[q], memcpy(ch[pre[q] = pre[np] = nq], ch[q], sizeof ch[q]);
14             while(p && ch[p][c] == q) ch[p][c] = nq, p = pre[p];
15         }
16     }
17 }
18 inline void dfs(int u) {
19     if(vis[u]) return ;
20     vis[u] = 1;
21     for(int c = 0 ; c < 26 ; ++ c) if(ch[u][c]) dfs(ch[u][c]);
22     int cnt = 0;
23     for(int c = 0 ; c < 26 ; ++ c) if(ch[u][c]) tmp[cnt ++] = sg[ch[u][c]];
24     sg[u] = cnt;
25     if(cnt) {
26         sort(tmp, tmp + cnt), cnt = unique(tmp, tmp + cnt) - tmp;
27         sg[u] = cnt;
28         for(int i = 0 ; i < cnt ; ++ i) if(i != tmp[i]) { sg[u] = i; break; }
29     }
30 }
31 int main() {
32     while(scanf("%s%d", s + 1, &n) == 2) {
33         int ans = tot = 0;
34         last = nd(0);
35         for(int i = 1 ; s[i] ; ++ i) ins(s[i] - 'a');
36         dfs(1);
37         for(int i = 1 ; i <= n ; ++ i) {
38             scanf("%s", s + 1);
39             int x = 1;
40             for(int j = 1 ; s[j] ; ++ j) x = ch[x][s[j] - 'a'];
41             ans ^= sg[x];
42         }
43         puts(ans ? "Alice" : "Bob");
44     }
45 }
loj #6377. 「是男人就过8题——Pony.ai」AStringGame
posted @ 2018-08-07 20:17  KingSann  阅读(245)  评论(0编辑  收藏  举报