【CF】556D A Lot of Games

构建trie树,可以得到4类结点:必胜点,必负点,完全主宰点(可胜可负),完全无法主宰点(无法控制最终胜负)。递归到叶子结点,即为必胜点,回溯分情况讨论。注意叶子结点使用属性n来控制,n表示当前结点的儿子结点的数目,叶子结点没有儿子。

  1 /* 456D */
  2 #include <iostream>
  3 #include <string>
  4 #include <map>
  5 #include <queue>
  6 #include <set>
  7 #include <stack>
  8 #include <vector>
  9 #include <deque>
 10 #include <algorithm>
 11 #include <cstdio>
 12 #include <cmath>
 13 #include <ctime>
 14 #include <cstring>
 15 #include <climits>
 16 #include <cctype>
 17 #include <cassert>
 18 using namespace std;
 19
 20 typedef struct trie_t {
 21     int n;
 22     int next[26];
 23     trie_t() {
 24         n = 0;
 25         memset(next, 0, sizeof(next));
 26     }
 27 } trie_t;
 28
 29 const int maxn = 1e5+5;
 30
 31 trie_t T[maxn];
 32 int L = 0;
 33 char s[maxn];
 34 int n, m;
 35
 36 int newTrie() {
 37     return ++L;
 38 }
 39
 40 void create(char *s, int rt) {
 41     int p = rt;
 42     int i = 0, id;
 43
 44     while (s[i]) {
 45         id = s[i] - ‘a‘;
 46         if (T[p].next[id] == 0) {
 47             T[p].next[id] = ++L;
 48             ++T[p].n;
 49         }
 50         p = T[p].next[id];
 51         ++i;
 52     }
 53 }
 54
 55 int dfs(int rt) {
 56     int i;
 57     int st = 0;
 58
 59     if (T[rt].n == 0)
 60         return 2;
 61
 62     for (i=0; i<26; ++i) {
 63         if (T[rt].next[i])
 64             st |= dfs(T[rt].next[i]);
 65     }
 66     switch(st) {
 67     case 0:
 68         return 3;
 69     case 1:
 70         return 2;
 71     case 2:
 72         return 1;
 73     case 3:
 74         return 0;
 75     default:
 76         return 0;
 77     }
 78 }
 79
 80
 81 int main() {
 82     int i, j, k;
 83
 84     #ifndef ONLINE_JUDGE
 85         freopen("data.in", "r", stdin);
 86         freopen("data.out", "w", stdout);
 87     #endif
 88
 89     scanf("%d %d", &n, &m);
 90     // build trie
 91     for (i=0; i<n; ++i) {
 92         scanf("%s", s);
 93         create(s, 0);
 94     }
 95     // get the key point
 96     int st = 0;
 97     for (i=0; i<26; ++i) {
 98         if (T[0].next[i])
 99             st |= dfs(T[0].next[i]);
100     }
101
102     if (st == 3) {
103         puts("First");
104         return 0;
105     } else if (st == 0) {
106         puts("Second");
107         return 0;
108     }
109     if (st == 1) {
110         puts("Second");
111         return 0;
112     }
113     if (m & 1) {
114         puts("First");
115     } else {
116         puts("Second");
117     }
118
119     #ifndef ONLINE_JUDGE
120         printf("time = %d.\n", (int)clock());
121     #endif
122
123     return 0;
124 }
时间: 2024-10-10 15:55:53

【CF】556D A Lot of Games的相关文章

【CF】38E Let&#39;s Go Rolling! (dp)

前言 这题还是有点意思的. 题意: 给你 \(n\) (\(n<=3000\)) 个弹珠,它们位于数轴上.给你弹珠的坐标 \(x_i\) 在弹珠 \(i\) 上面花费 \(C_i\) 的钱 可以使弹珠在原地不动 (\(-10^9<=x_i,C_i<=10^9\)),游戏开始时,所有的弹珠向左滚动,直到碰到定在原地不动的弹珠,其花费是其滚动的距离.总花费=开始前的花费+弹珠滚动的花费,问最小的花费是多少 题解 首先划分出阶段,,我们可以先将弹珠排序,前 \(i\) 个弹珠,最后一个固定的弹

【CF】codeforces round 369(div2)

*明早起来再贴代码 A [题意] 给定n*5的方格 将横向的相邻两个变成+输出   [题解] ...   B [题意] 一个n*n的正整数矩阵,有且仅有一个数为0 ,在这个位置填上一个数,使得每一列的和 每一行的和 两条对角线各自的和都相等 输出这个数   [题解]sb题.暴力一下.注意细节,否则你就像这样 (不是本人   C [题意] 一排点,用1~n表示,熊孩子要给这些点上色.最初每个点的颜色为ci.一共有m种颜色,如果ci=0表示这个点最初无色. 熊孩子们需要给最初为无色的点涂上色,往第i

【CF】Codeforces Round #361 (Div. 2)

难得有想法写一整套题解 首先想说的是,这场CF,我感觉是div2极为不错的一场(对于中档选手<因为我就出了三题,还掉了一个-- 说笑了,感觉这一场很耐人寻味.就是那种抓破头皮想不出,知道做法后细细品味,有种   哦~~~~~这样啊~~~~好神奇!!! 的感觉 首先..秀一下战绩 不多说了 都在题里 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ A. Mike and Cellphone time limit per test 1 second memory limit per test 256 megaby

【CF】掉分总结

比赛总结 前情提要 自从前段时间连续掉分,就心态崩了,还是自己太菜,一直想写个总结,看看这几场比赛都干了啥,以后准备怎么办.鸽了这么久的总结,是该写写了. 这是正文 首先大致提一下情感曲线(菜的真实): 那一晚,那一夜,sc大佬突然qq发消息给我,"打cf吗",我眉头一紧,这个cf莫非是穿越火线?又一想大佬才不会玩这种游戏,又一想,难道是codeforces?我颤颤巍巍的回了"codeforces?",大佬回的很快,扔给我了个链接,并说"这是616,你做吧

【CF】121 Div.1 C. Fools and Roads

题意是给定一棵树.同时,给定如下k个查询: 给出任意两点u,v,对u到v的路径所经过的边进行加计数. k个查询后,分别输出各边的计数之和. 思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.然后dfs求解各边的计数. 1 /* 191C */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #inc

【CF】207 Div.1 B.Xenia and Hamming

这题目一看很牛逼,其实非常easy.求求最小公倍数,最大公约数,均摊复杂度其实就是O(n). 1 /* 356B */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <dequ

【CF】283D Tennis Game

枚举t加二分判断当前t是否可行,同时求出s.注意不能说|a[n]| <= |3-a[n]|就证明无解,开始就是wa在这儿了.可以简单想象成每当a[n]赢的时候,两人都打的难解难分(仅多赢一轮):而每当a[n]输的时候,一轮都没赢.在这个前提下,显然存在|a[n]| <= |3-a[n]|. 1 /* 283D */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include &l

【CF】196 Div.2 Book of Evil

显然这个图是一课树,看着题目首先联想到LCA(肯定是可以解的).但是看了一下数据大小,应该会TLE.然后,忽然想到一个前面做过的题目,大概是在一定条件下树中某结点旋转成为根后查询最长路径.结果灵感就来了,主要思路是对于每个结点,第一次dfs得到两个变量到P结点的最大值以及次大值.然后,第二次dfs对于当前结点u,u到它的子树中P类结点的最大距离已知(nd[u].mx),那么除u的其他结点v到P类结点的最大距离加上v到u的距离和的最大值为pmx,可以通过每次深搜计算出来,只要d大于等于两者的最大值

【CF】3B Lorry

这道题目网上有几个题解,均有问题.其实就是简单的贪心+排序,没必要做的那么复杂.一旦tot+curv > v时,显然curv==2, 有三种可能:(1)取出最小的curv==1的pp,装入当前的p:(2)取出后续最大的curv==1的p,并且装入:(3)当前已经是最优的(即后续不存在curv==1的类型),同时前一个的pp比当前的p更优.(这种情况不需要特判) 1 /* 3B */ 2 #include <iostream> 3 #include <string> 4 #in