Gemini Boy - ACM之路~
Codeforces 291E. Tree-String Problem
链接:http://codeforces.com/problemset/problem/291/E
题意就是说给你一棵树,边权是字符串,然后从根节点到叶子节点的所有路径中,出现模板串的个数。
做法就是dfs+kmp,对目标串得到next数组,然后从根节点dfs,一边dfs一边跑kmp进行匹配。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> #include <string> using namespace std; const int maxn = 100100; struct Edge { int to; string s; Edge() {} Edge(int too, string str) { to = too; s = str; } }; int n, ans = 0, next[maxn]; string t; vector<Edge> edge[maxn]; void dfs(int u, int k) { for (int l = 0; l < edge[u].size(); l++) { int v = edge[u][l].to; string str = edge[u][l].s; int tmp = k, len = edge[u][l].s.size(); for (int i = 0, j = k; i < len; i++) { while (j != -1 && str[i] != t[j+1]) j = next[j]; if (str[i] == t[j+1]) j++; if (j + 1 == t.size()) { j = next[j]; ans++; } tmp = j; } dfs(v, tmp); } } void work() { cin >> n; for (int i = 2; i <= n; i++) { int p; string str; cin >> p >> str; edge[p].push_back(Edge(i, str)); } cin >> t; next[0] = -1; for (int i = 1, j = -1; i < t.size(); i++) { while (j != -1 && t[j+1] != t[i]) j = next[j]; if (t[j+1] == t[i]) { next[i] = j + 1; j++; } else { next[i] = -1; } } dfs(1, -1); cout << ans << endl; } int main() { work(); return 0; }
Codeforces有质量水题集锦
Codeforces 280B: Maximum Xor Secondary
链接:http://codeforces.com/problemset/problem/280/B
题意:给定一个序列,求对于任意L,R,在LR之间最大值与严格次大值异或值最大是多少。
做法:维护一个优先序列,可以证明每个元素最多只会进队一次出队一次,所以复杂度是O(n)的。
代码君:http://codeforces.com/contest/280/submission/3852565
Codeforces 280C: Game on Tree
链接:http://codeforces.com/contest/280/problem/C
题意:给一棵树,每次随机的删除一个结点和这个结点的子树,问删除整个树期望要删多少次
做法:每个结点的depth的倒数和即为最终结果,(不会证明)
代码君:http://codeforces.com/contest/280/submission/3852624
Codeforces(tag: Dynamic Programming)
keng
Codeforces(tag: Data Structures)
Codeforces 4C: Registration system
链接:http://codeforces.com/problemset/problem/4/C
题意:统计重复子串的个数
做法:map水过0.0,也可以写trie树什么的。
代码君:http://codeforces.com/contest/4/submission/3823233
Codeforces 5C: Longest Regular Bracket Sequence
链接:http://codeforces.com/problemset/problem/5/C
题意:统计长度最长的可以两两配对的括号的长度及个数
做法:用个栈。扫一遍就行了。
代码君:http://codeforces.com/contest/5/submission/3823221