C - Tachibana Kanade's Tofu

思路:把 n 个串丢进AC自动机中,然后dp就好啦。 我的代码居然是在CF上跑最快的。。

  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. #define fi first
  4. #define se second
  5. #define mk make_pair
  6. #define PLL pair<LL, LL>
  7. #define PLI pair<LL, int>
  8. #define PII pair<int, int>
  9. #define SZ(x) ((int)x.size())
  10. #define ull unsigned long long
  11.  
  12. using namespace std;
  13.  
  14. const int N = + ;
  15. const int inf = 0x3f3f3f3f;
  16. const LL INF = 0x3f3f3f3f3f3f3f3f;
  17. const int mod = 1e9 + ;
  18. const double eps = 1e-;
  19. const double PI = acos(-);
  20.  
  21. int n, m, len, k, tmp, v[];
  22. vector<int> L, R;
  23. vector<int> s;
  24.  
  25. inline void add(int &a, int b) {
  26. a += b; if(a >= mod) a -= mod;
  27. }
  28.  
  29. struct Ac {
  30. int ch[][], val[], f[], tot, sz;
  31. int dp[][][][], cur, pre;
  32. void init(int _sz) {tot = ; sz = _sz;}
  33. inline int newNode() {
  34. tot++; f[tot] = ; val[tot] = ;
  35. memset(ch[tot], , sizeof(ch[tot]));
  36. return tot;
  37. }
  38. inline int idx(int c) {return c;}
  39. void addStr(vector<int> &s, int cost) {
  40. int u = ;
  41. for(int i = ; i < s.size(); i++) {
  42. int c = idx(s[i]);
  43. if(!ch[u][c]) ch[u][c] = newNode();
  44. u = ch[u][c];
  45. }
  46. val[u] += cost;
  47. }
  48. void build() {
  49. queue<int> que;
  50. for(int c = ; c < sz; c++) {
  51. int v = ch[][c];
  52. if(!v) ch[][c] = ;
  53. else f[v] = , que.push(v);
  54. }
  55. while(!que.empty()) {
  56. int u = que.front(); que.pop();
  57. val[u] += val[f[u]];
  58. for(int c = ; c < sz; c++) {
  59. int v = ch[u][c];
  60. if(!v) ch[u][c] = ch[f[u]][c];
  61. else f[v] = ch[f[u]][c], que.push(v);
  62. }
  63. }
  64. }
  65. int solve(vector<int> &str) {
  66. int n = str.size(), ans = ;
  67. cur = , pre = ;
  68. memset(dp[cur], , sizeof(dp[cur]));
  69. for(int z = ; z <= str[]; z++) {
  70. int v = ch[][z];
  71. if(val[v] <= k) add(dp[cur][v][val[v]][z == str[]], );
  72. }
  73. for(int i = ; i < n; i++) {
  74. swap(cur, pre);
  75. memset(dp[cur], , sizeof(dp[cur]));
  76. for(int z = ; z < m; z++) {
  77. int v = ch[][z];
  78. if(val[v] <= k) add(dp[cur][v][val[v]][], );
  79. }
  80. for(int u = ; u <= tot; u++) {
  81. for(int s = ; s <= k; s++) {
  82. if(dp[pre][u][s][]) {
  83. for(int z = ; z < m; z++) {
  84. int v = ch[u][z];
  85. if(s+val[v] <= k) add(dp[cur][v][val[v]+s][], dp[pre][u][s][]);
  86. }
  87. }
  88.  
  89. if(dp[pre][u][s][]) {
  90. for(int z = ; z <= str[i]; z++) {
  91. int v = ch[u][z];
  92. if(s+val[v] <= k) add(dp[cur][v][val[v]+s][z==str[i]], dp[pre][u][s][]);
  93. }
  94. }
  95. }
  96. }
  97. }
  98. for(int u = ; u <= tot; u++)
  99. for(int j = ; j <= k; j++)
  100. add(ans, dp[cur][u][j][]), add(ans, dp[cur][u][j][]);
  101. return ans;
  102. }
  103. } ac;
  104.  
  105. int main() {
  106. scanf("%d%d%d", &n, &m, &k);
  107. ac.init(m);
  108. scanf("%d", &len); L.resize(len);
  109. for(int i = ; i < len; i++) scanf("%d", &L[i]);
  110. scanf("%d", &len); R.resize(len);
  111. for(int i = ; i < len; i++) scanf("%d", &R[i]);
  112. for(int i = ; i < n; i++) {
  113. scanf("%d", &len); s.resize(len);
  114. for(int j = ; j < len; j++) scanf("%d", &s[j]);
  115. int cost; scanf("%d", &cost);
  116. ac.addStr(s, cost);
  117. for(int p = ; p+s.size() <= L.size(); p++) {
  118. bool flag = true;
  119. for(int q = ; q < s.size(); q++) {
  120. if(s[q] != L[q+p]) {
  121. flag = false;
  122. break;
  123. }
  124. }
  125. if(flag) tmp += cost;
  126. }
  127. }
  128. ac.build();
  129. int ans = (ac.solve(R) - ac.solve(L) + (tmp <= k) + mod) % mod;
  130. printf("%d\n", ans);
  131. return ;
  132. }
  133. /*
  134. */

Codeforces Round #248 (Div. 1) C - Tachibana Kanade's Tofu AC自动机的更多相关文章

  1. Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note

    题目链接:http://codeforces.com/contest/433/problem/C 思路:可以想到,要把某一个数字变成他的相邻中的数字的其中一个,这样总和才会减少,于是我们可以把每个数的 ...

  2. Codeforces Round #248 (Div. 2)C 题

    题目:http://codeforces.com/contest/433/problem/C 没想到做法就各种纠结, 今天做的都快疯掉了, 太弱了, 等题解一出,就各种恍然大悟 不应该不应该 正文: ...

  3. Codeforces Round #248 (Div. 2) (ABCD解决问题的方法)

    比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory ...

  4. Codeforces Round #248 (Div. 1) B. Nanami's Digital Board 暴力 前缀和

    B. Nanami's Digital Board 题目连接: http://www.codeforces.com/contest/434/problem/B Description Nanami i ...

  5. Codeforces Round #248 (Div. 1) A. Ryouko's Memory Note 水题

    A. Ryouko's Memory Note 题目连接: http://www.codeforces.com/contest/434/problem/A Description Ryouko is ...

  6. Codeforces Round #248 (Div. 2) B称号 【数据结构:树状数组】

    主题链接:http://codeforces.com/contest/433/problem/B 题目大意:给n(1 ≤ n ≤ 105)个数据(1 ≤ vi ≤ 109),当中有m(1 ≤ m ≤  ...

  7. Codeforces Round #248 (Div. 2) B. Kuriyama Mirai's Stones

    题目简单描述就是求数组中[l,r]区间的和 #include <iostream> #include <vector> #include <string> #inc ...

  8. Codeforces Round #248 (Div. 2) A. Kitahara Haruki's Gift

    解决思路是统计100的个数为cnt1,200的个数为cnt2 则 cnt1    cnt2 奇数      奇数 奇数      偶数 偶数      奇数 偶数     偶数 当cnt1为奇数时一定 ...

  9. Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note (vector 替换)

    题目链接 题意:给m个数字, 这些数字都不大于 n,  sum的值为相邻两个数字 差的绝对值.求这n个数字里把一个数字 用 其中另一个数字代替以后, 最小的sum值. 分析:刚开始以为两个for 最坏 ...

随机推荐

  1. Python设计模式(六大)

    1.外观模式(Facade) 一层一层向上封装,灵活性会降低,功能完成度高,和python的模块比较像,但对于封装好了的类,将会变得很简单,简洁. 2.六大设计原则 单一职责原则 (Single Re ...

  2. ASP.NET根据IP获取省市地址

    1.在网站的跟路径下面添加 QQWry.dat 文件,这个文件是IP数据库文件 2.添加以下一个类 IPScanner     C# 代码   复制 public class IPScanner { ...

  3. 分享自己新做的vim colorscheme

    把下面的内容保存成darkslategrey.vim,放入~/.vim/colors目录即可. " Vim color file " Maintainer: jiqing() &q ...

  4. 【算法专题】后缀自动机SAM

    后缀自动机是用于识别子串的自动机. 学习推荐:陈立杰讲稿,本文记录重点部分和感性理解(论文语言比较严格). 刷题推荐:[后缀自动机初探],题目都来自BZOJ. [Right集合] 后缀自动机真正优于后 ...

  5. Trying to get property of non-object

    原文:http://www.jb51.net/article/29878.htm 总结:判断为空用 if(isset($v)){}代替if($v == null){}

  6. Linux查看日志三种命令

    第一种:查看实时变化的日志(比较吃内存) 最常用的: tail -f filename (默认最后10行,相当于增加参数 -n 10) Ctrl+c 是退出tail命令   其他情况: tail -n ...

  7. js 禁用右键菜单、拖拽、选中、复制

    //禁用拖拽 document.ondragstart = function () { return false; }; /** * 禁用右键菜单 */ document.oncontextmenu ...

  8. 2016.6.1——Min Stack

    Min Stack 本题收获: 1.可以利用两个栈操作. 2.栈的基本操作. 题目: Design a stack that supports push, pop, top, and retrievi ...

  9. 使用纯注解与配置类开发springMVC项目,去掉xml配置

    最近拜读了杨开振老师的书,深入浅出springBoot2.x,挖掘了很多以前被忽略的知识, 开发一年多,工作中一直用传统springmvc的开发,基本都还是用的传统的xml配置开发, 看到书里有提到, ...

  10. poj1056

    简单题 #include <iostream> #include <string> using namespace std; struct cnode { cnode *pze ...