Codeforces Round #248 (Div. 1) C - Tachibana Kanade's Tofu AC自动机
思路:把 n 个串丢进AC自动机中,然后dp就好啦。 我的代码居然是在CF上跑最快的。。
- #include<bits/stdc++.h>
- #define LL long long
- #define fi first
- #define se second
- #define mk make_pair
- #define PLL pair<LL, LL>
- #define PLI pair<LL, int>
- #define PII pair<int, int>
- #define SZ(x) ((int)x.size())
- #define ull unsigned long long
- using namespace std;
- const int N = + ;
- const int inf = 0x3f3f3f3f;
- const LL INF = 0x3f3f3f3f3f3f3f3f;
- const int mod = 1e9 + ;
- const double eps = 1e-;
- const double PI = acos(-);
- int n, m, len, k, tmp, v[];
- vector<int> L, R;
- vector<int> s;
- inline void add(int &a, int b) {
- a += b; if(a >= mod) a -= mod;
- }
- struct Ac {
- int ch[][], val[], f[], tot, sz;
- int dp[][][][], cur, pre;
- void init(int _sz) {tot = ; sz = _sz;}
- inline int newNode() {
- tot++; f[tot] = ; val[tot] = ;
- memset(ch[tot], , sizeof(ch[tot]));
- return tot;
- }
- inline int idx(int c) {return c;}
- void addStr(vector<int> &s, int cost) {
- int u = ;
- for(int i = ; i < s.size(); i++) {
- int c = idx(s[i]);
- if(!ch[u][c]) ch[u][c] = newNode();
- u = ch[u][c];
- }
- val[u] += cost;
- }
- void build() {
- queue<int> que;
- for(int c = ; c < sz; c++) {
- int v = ch[][c];
- if(!v) ch[][c] = ;
- else f[v] = , que.push(v);
- }
- while(!que.empty()) {
- int u = que.front(); que.pop();
- val[u] += val[f[u]];
- for(int c = ; c < sz; c++) {
- int v = ch[u][c];
- if(!v) ch[u][c] = ch[f[u]][c];
- else f[v] = ch[f[u]][c], que.push(v);
- }
- }
- }
- int solve(vector<int> &str) {
- int n = str.size(), ans = ;
- cur = , pre = ;
- memset(dp[cur], , sizeof(dp[cur]));
- for(int z = ; z <= str[]; z++) {
- int v = ch[][z];
- if(val[v] <= k) add(dp[cur][v][val[v]][z == str[]], );
- }
- for(int i = ; i < n; i++) {
- swap(cur, pre);
- memset(dp[cur], , sizeof(dp[cur]));
- for(int z = ; z < m; z++) {
- int v = ch[][z];
- if(val[v] <= k) add(dp[cur][v][val[v]][], );
- }
- for(int u = ; u <= tot; u++) {
- for(int s = ; s <= k; s++) {
- if(dp[pre][u][s][]) {
- for(int z = ; z < m; z++) {
- int v = ch[u][z];
- if(s+val[v] <= k) add(dp[cur][v][val[v]+s][], dp[pre][u][s][]);
- }
- }
- if(dp[pre][u][s][]) {
- for(int z = ; z <= str[i]; z++) {
- int v = ch[u][z];
- if(s+val[v] <= k) add(dp[cur][v][val[v]+s][z==str[i]], dp[pre][u][s][]);
- }
- }
- }
- }
- }
- for(int u = ; u <= tot; u++)
- for(int j = ; j <= k; j++)
- add(ans, dp[cur][u][j][]), add(ans, dp[cur][u][j][]);
- return ans;
- }
- } ac;
- int main() {
- scanf("%d%d%d", &n, &m, &k);
- ac.init(m);
- scanf("%d", &len); L.resize(len);
- for(int i = ; i < len; i++) scanf("%d", &L[i]);
- scanf("%d", &len); R.resize(len);
- for(int i = ; i < len; i++) scanf("%d", &R[i]);
- for(int i = ; i < n; i++) {
- scanf("%d", &len); s.resize(len);
- for(int j = ; j < len; j++) scanf("%d", &s[j]);
- int cost; scanf("%d", &cost);
- ac.addStr(s, cost);
- for(int p = ; p+s.size() <= L.size(); p++) {
- bool flag = true;
- for(int q = ; q < s.size(); q++) {
- if(s[q] != L[q+p]) {
- flag = false;
- break;
- }
- }
- if(flag) tmp += cost;
- }
- }
- ac.build();
- int ans = (ac.solve(R) - ac.solve(L) + (tmp <= k) + mod) % mod;
- printf("%d\n", ans);
- return ;
- }
- /*
- */
Codeforces Round #248 (Div. 1) C - Tachibana Kanade's Tofu AC自动机的更多相关文章
- Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note
题目链接:http://codeforces.com/contest/433/problem/C 思路:可以想到,要把某一个数字变成他的相邻中的数字的其中一个,这样总和才会减少,于是我们可以把每个数的 ...
- Codeforces Round #248 (Div. 2)C 题
题目:http://codeforces.com/contest/433/problem/C 没想到做法就各种纠结, 今天做的都快疯掉了, 太弱了, 等题解一出,就各种恍然大悟 不应该不应该 正文: ...
- Codeforces Round #248 (Div. 2) (ABCD解决问题的方法)
比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory ...
- 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 ...
- 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 ...
- Codeforces Round #248 (Div. 2) B称号 【数据结构:树状数组】
主题链接:http://codeforces.com/contest/433/problem/B 题目大意:给n(1 ≤ n ≤ 105)个数据(1 ≤ vi ≤ 109),当中有m(1 ≤ m ≤ ...
- Codeforces Round #248 (Div. 2) B. Kuriyama Mirai's Stones
题目简单描述就是求数组中[l,r]区间的和 #include <iostream> #include <vector> #include <string> #inc ...
- Codeforces Round #248 (Div. 2) A. Kitahara Haruki's Gift
解决思路是统计100的个数为cnt1,200的个数为cnt2 则 cnt1 cnt2 奇数 奇数 奇数 偶数 偶数 奇数 偶数 偶数 当cnt1为奇数时一定 ...
- Codeforces Round #248 (Div. 2) C. Ryouko's Memory Note (vector 替换)
题目链接 题意:给m个数字, 这些数字都不大于 n, sum的值为相邻两个数字 差的绝对值.求这n个数字里把一个数字 用 其中另一个数字代替以后, 最小的sum值. 分析:刚开始以为两个for 最坏 ...
随机推荐
- Python设计模式(六大)
1.外观模式(Facade) 一层一层向上封装,灵活性会降低,功能完成度高,和python的模块比较像,但对于封装好了的类,将会变得很简单,简洁. 2.六大设计原则 单一职责原则 (Single Re ...
- ASP.NET根据IP获取省市地址
1.在网站的跟路径下面添加 QQWry.dat 文件,这个文件是IP数据库文件 2.添加以下一个类 IPScanner C# 代码 复制 public class IPScanner { ...
- 分享自己新做的vim colorscheme
把下面的内容保存成darkslategrey.vim,放入~/.vim/colors目录即可. " Vim color file " Maintainer: jiqing() &q ...
- 【算法专题】后缀自动机SAM
后缀自动机是用于识别子串的自动机. 学习推荐:陈立杰讲稿,本文记录重点部分和感性理解(论文语言比较严格). 刷题推荐:[后缀自动机初探],题目都来自BZOJ. [Right集合] 后缀自动机真正优于后 ...
- Trying to get property of non-object
原文:http://www.jb51.net/article/29878.htm 总结:判断为空用 if(isset($v)){}代替if($v == null){}
- Linux查看日志三种命令
第一种:查看实时变化的日志(比较吃内存) 最常用的: tail -f filename (默认最后10行,相当于增加参数 -n 10) Ctrl+c 是退出tail命令 其他情况: tail -n ...
- js 禁用右键菜单、拖拽、选中、复制
//禁用拖拽 document.ondragstart = function () { return false; }; /** * 禁用右键菜单 */ document.oncontextmenu ...
- 2016.6.1——Min Stack
Min Stack 本题收获: 1.可以利用两个栈操作. 2.栈的基本操作. 题目: Design a stack that supports push, pop, top, and retrievi ...
- 使用纯注解与配置类开发springMVC项目,去掉xml配置
最近拜读了杨开振老师的书,深入浅出springBoot2.x,挖掘了很多以前被忽略的知识, 开发一年多,工作中一直用传统springmvc的开发,基本都还是用的传统的xml配置开发, 看到书里有提到, ...
- poj1056
简单题 #include <iostream> #include <string> using namespace std; struct cnode { cnode *pze ...