中文题目:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=563&pid=1003

首先贴一下bc的题解:

首先我们考虑m=1的情况。给定两个数组A={a1,a2,…,an}和B={b1,b2,…,bk},问B在A中出现了几次。令ci=ai+1ai,1≤i<n,同样令di=bi+1bi,1≤i<k,那么上述问题可以转化为ci和di的模式匹配问题,这个正确性显然,也没有什么好证明的。于是对于m=1的情况只有用个kmp即可搞定。

现在考虑m>1的情况,我们考虑用ac自动机来做。考虑到字符集并不是普通的数字,而是一个分数,我们不放搞个分数类,然后用map存转移边。用m个模式串(Bob的序列)建好自动机之后,把文本串(Alice的序列)在自动机上跑一遍即可统计出答案。

事实上,这个题的精华就在于序列变换,将问题转化为多模板匹配问题。而且由于转化后的序列有二维状态,可以用map映射重新为状态分配一个值(类似离散)。另外由于字符集比较大,所以ac自动机里面需要一点小小的修改,原来的二维数组的第二维需用map,另外需要同时记录所有儿子的字符值。原来的模板只需要小改就可以适应这种情况了。详见代码:

 #pragma comment(linker, "/STACK:10240000,10240000")

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <map>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <ctime>
#include <cctype>
#include <set>
#include <bitset>
#include <functional>
#include <numeric>
#include <stdexcept>
#include <utility> using namespace std; #define mem0(a) memset(a, 0, sizeof(a))
#define mem_1(a) memset(a, -1, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define define_m int m = (l + r) >> 1
#define rep_up0(a, b) for (int a = 0; a < (b); a++)
#define rep_up1(a, b) for (int a = 1; a <= (b); a++)
#define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
#define rep_down1(a, b) for (int a = b; a > 0; a--)
#define all(a) (a).begin(), (a).end()
#define lowbit(x) ((x) & (-(x)))
#define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
#define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
#define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
#define pchr(a) putchar(a)
#define pstr(a) printf("%s", a)
#define sstr(a) scanf("%s", a)
#define sint(a) scanf("%d", &a)
#define sint2(a, b) scanf("%d%d", &a, &b)
#define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define pint(a) printf("%d\n", a)
#define test_print1(a) cout << "var1 = " << a << endl
#define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
#define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi; const int dx[] = {, , -, , , , -, -};
const int dy[] = {-, , , , , -, , - };
const int maxn = 3e4 + ;
const int md = ;
const int inf = 1e9 + ;
const LL inf_L = 1e18 + ;
const double pi = acos(-1.0);
const double eps = 1e-; template<class T>T gcd(T a, T b){return b==?a:gcd(b,a%b);}
template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
template<class T>T condition(bool f, T a, T b){return f?a:b;}
template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
int make_id(int x, int y, int n) { return x * n + y; } LL ans; struct AhoCorasickAutoMata {
const static int maxn = ;
int cc;
map<int, int> ch[maxn];
vector<int> son[maxn];
int val[maxn], last[maxn], f[maxn]; void clear() { cc = ; mem0(val); mem0(ch); mem0(last); mem0(f); rep_up0(i, maxn) { son[i].clear(); ch[i].clear(); } } void Insert(int s[], int n) {
int pos = ;
rep_up0(i, n) {
int id = s[i];
if(!ch[pos][id]) {
ch[pos][id] = ++ cc;
son[pos].push_back(id);
}
pos = ch[pos][id];
}
val[pos] ++;
} void print(int j) {
if (j) {
ans += val[j];
print(last[j]);
}
} void find(int T[], int n) {
int j = ;
rep_up0(i, n) {
int c = T[i];
while (j && !ch[j][c]) j = f[j];
j = ch[j][c];
if (val[j]) print(j);
else {
if (last[j]) print(last[j]);
}
}
} int getFail() {
queue<int> q;
f[] = ;
int SZ = son[].size();
rep_up0(i, SZ) {
int c = son[][i];
int u = ch[][c];
q.push(u);
}
while (!q.empty()) {
int r = q.front(), SZ = son[r].size(); q.pop();
rep_up0(i, SZ) {
int c = son[r][i];
int u = ch[r][c];
q.push(u);
int v = f[r];
while (v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]]? f[u] : last[f[u]];
}
}
}
}; AhoCorasickAutoMata ac;
map<pii, int> mp;
int pa[], pb[];
int a[], b[]; int main() {
//freopen("in.txt", "r", stdin);
int T, n, m, tot = ;
cin >> T;
while (T--) {
ans = ;
ac.clear();
mp.clear();
cin >> n >> m;
rep_up0(i, n) {
sint(a[i]);
}
rep_up0(i, n - ) {
int g = gcd(a[i], a[i + ]);
int ga = a[i] / g, gb = a[i + ] / g;
int &x = mp[make_pair(ga, gb)];
if (!x) x = ++ tot;
pa[i] = x;
} rep_up0(i, m) {
int k;
sint(k);
rep_up0(j, k) {
sint(b[j]);
}
if (k > n) continue;
if (k == ) {
ans += n;
continue;
}
rep_up0(j, k - ) {
int g = gcd(b[j], b[j + ]);
int ga = b[j] / g, gb = b[j + ] / g;
int &x = mp[make_pair(ga, gb)];
if (!x) x = ++ tot;
pb[j] = x;
}
ac.Insert(pb, k - );
}
ac.getFail();
ac.find(pa, n - );
cout << ans << endl;
}
return ;
}

[hdu5164]ac自动机的更多相关文章

  1. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  2. AC自动机-算法详解

    What's Aho-Corasick automaton? 一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一. 简单的说,KMP用来在一篇文章中匹配一个模式串:但 ...

  3. python爬虫学习(11) —— 也写个AC自动机

    0. 写在前面 本文记录了一个AC自动机的诞生! 之前看过有人用C++写过AC自动机,也有用C#写的,还有一个用nodejs写的.. C# 逆袭--自制日刷千题的AC自动机攻克HDU OJ HDU 自 ...

  4. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  5. BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3198  Solved: 1532[Submit][Status ...

  6. BZOJ 1212: [HNOI2004]L语言 [AC自动机 DP]

    1212: [HNOI2004]L语言 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1367  Solved: 598[Submit][Status ...

  7. [AC自动机]【学习笔记】

    Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To ...

  8. AC自动机 HDU 3065

    大概就是裸的AC自动机了 #include<stdio.h> #include<algorithm> #include<string.h> #include< ...

  9. AC自动机 HDU 2896

    n个字串 m个母串 字串在母串中出现几次 #include<stdio.h> #include<algorithm> #include<string.h> #inc ...

随机推荐

  1. vue2.x学习笔记(七)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12576797.html. 条件渲染 vue也提供了一些指令,用于条件性地渲染模板中的内容. [v-if]和[v-e ...

  2. 4. js

    1.) ~   操作符 console.log(~-2)  // 1 console.log(~-1)  // 0 console.log(~0)  // -1 console.log(~1)  // ...

  3. Django文档阅读-Day2

    Django文档阅读 - Day2 Writing your first Django app, part 1 You can tell Django is installed and which v ...

  4. apache虚拟主机配置-域名/IP和端口两种配置

    由于百度上有非常详细的资料,我这里就转载而已:https://jingyan.baidu.com/article/4f7d5712d48a191a201927e0.html

  5. css3 文本控制自动换行

    text-overflow:ellipsis; white-space:nowrap; overflow:hidden;

  6. SQLI-LABS学习笔记(二)

    逼话少说,如有错误,烦请指出,谢谢 这两天生病,效率很低 第5关 打开页面 发现跟前几题不同,没有直接返回数据.. 加个单引号 You have an error in your SQL syntax ...

  7. Docker镜像与仓库(四)

    Dockerfile方式创建镜像 https://hub.docker.com/_/centos/ #找一个centos6.6 的dockerfile链接 [root@linux-node1 ~]# ...

  8. 数据结构入门第二课(浙大mooc)

    数据结构入门第二课 目录 数据结构入门第二课 引子 多项式的表示 方法1 顺序结构表示多项式各项 方法2 顺序结构表示非零项 方法3 链表结构存储非零项 多项式问题的启示 线性表 线性表的抽象数据类型 ...

  9. gitlab环境部署

    一:配置主机名 [root@localhost ~]# hostname gitlab[root@localhost ~]# bash 二:安装依赖包 [root@gitlab ~]# yum -y ...

  10. 利用CRM实现电话营销部门的管控 之数据暂缓

    每个公司都有相应的电话营销部门,有的公司是使用的集中的Call Center,有的公司则是使用简单的销售软件.不同的公司都有各自运行管理的方法. 此篇文章主要是介绍基于微软Dynamic CRM下的自 ...