hdu 5164 Matching on Array AC自动机
来源:互联网 发布:linux stdin 编辑:程序博客网 时间:2024/05/01 17:09
Matching on Array
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 257 Accepted Submission(s): 61
Problem Description
Alice has a sequence {a1,a2,…,an} with n positive integers. Bob has some positive integer sequences with different size. Alice wants to know the total occurrences of every sequence Bob has in Alice's sequence (the occurrences are allowed to overlap).
We say one sequenceB occurs in another sequence A if there is a contiguous subsequence of A that is the same as B after scaled by a positive real factor.
For exampleA={2,4,8,16},B={1,2} then B occurs three times in A . The occurrences are {2,4} ,{4,8} and {8,16} . And the factor is 0.5, 0.25 and 0.125.
We say one sequence
For example
Input
There are multiple test cases. The first line of input contains an integerT (1≤T≤30) , indicating the number of test cases. For each test case:
The first line contains two integern and m (1≤n,m≤100000) , indicating the size of Alice's sequence and the number of sequences Bob has. In the next line, there aren integers, a1,a2,…,an , indicating Alice's sequence. In the following m lines, each starts with an integer ki(1≤ki≤300000) - the size of the sequence. Then ki space separated positive integers follow, indicating the sequence.
The total sum ofki is less than or equal to 1000000. Other integers are between 1 and 10000, inclusive.
The first line contains two integer
The total sum of
Output
For each test case, output a single line with a single integer, indicating the total number of occurrences.
Sample Input
24 12 4 8 162 1 25 32 4 2 4 63 1 2 11 52 16 8
Sample Output
37HintFor sample 1, please refer to the problem description. For sample 2, {1, 2, 1} occurs only once, {5} occurs five times and {16, 8} occurs only once.思路: 如果是单纯的在文本串中找模式串,可以用KMP或者BM,算法讲解 如果是多个模式串,就需要用AC自动机。AC自动机:点击打开链接 大神讲解的很是清楚。乘以任意的factor,使俩个串相等,那么前提条件肯定是每个串之间的比值肯定是一样的。A{x1, x2, x3……} B{y1, y2, y3……}如果存在 B* p = A 必然, x2/ x1 = y2 / y1 ; x3/x2 = y3/y2;先把数据转换一下,利用AC自动机就可以了。需要注意 ans 的范围会爆 int { n = 100000; m = 100000 ; Bob序列每行只有一个数字,那么ans = n * m;}一开始,我用map<double, Tree *> 去记录字典树中每个节点的子节点;不过用double 多少害怕会有误差。 解决方法是用 node()结构体储存 被除数和除数约分后的值。不过验证过了,用double是可以AC的,#include<stdio.h>#include<string.h>#include<math.h>#include<string>#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<list>#include<map>#include<set>using namespace std;int n, m;int a[100010], b[300010];int kind;long long ans;struct Tree{ map<int, Tree* >next; vector<int>v; Tree *fail; int cnt; Tree(){ next.clear(); v.clear(); cnt = 0; fail = NULL; }};vector<int>e;Tree *root;struct node{ int x,y; bool operator < (const node &p)const{ if(x == p.x) return y < p.y; return x < p.x; } bool operator == (const node &p)const{ return x == p.x && y == p.y; } node(int x = 0, int y = 0):x(x), y(y) {}};node alice[100010];vector<node>idx;int gcd(int x, int y){ if(y == 0) return x; else return gcd(y, x % y);}node deal_gcd(int x, int y){ int r = gcd(x, y); x /= r; y /= r; return node(x, y);}void tree_add(){ Tree *p = root; for(int i = 0; i < e.size(); i++){ if(p->next[e[i]] == NULL){ p->v.push_back(e[i]); p->next[e[i]] = new Tree(); } p = p->next[e[i]]; } p->cnt ++;}bool march(node p, node q){ if(p == q) return 1; else return 0;}void deal_init_bob(){ int len; scanf("%d", &len); for(int i = 0; i < len; i++) scanf("%d", &b[i]); if(len > n) return; if(len == 1){ ans += n; return ; } e.clear(); for(int i = 1; i < len; i++){ node tp =deal_gcd(b[i], b[i - 1]); int id = lower_bound(idx.begin(), idx.end(), tp) - idx.begin(); if(id >=idx.size() || march(tp, idx[id]) == 0) return ; e.push_back(id); } tree_add();}void deal_init(){ scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) scanf("%d", &a[i]); idx.clear(); for(int i = 1; i < n; i++){ alice[i] = deal_gcd(a[i], a[i - 1]);// printf("alice[%d] = %d %d\n",i, alice[i].x, alice[i].y); idx.push_back(alice[i]); } sort(idx.begin(), idx.end()); idx.erase(unique(idx.begin(), idx.end()), idx.end());// for(int i = 0; i < idx.size(); i++)// printf("i = %d, x=%d, y= %d\n", i, idx[i].x, idx[i].y); for(int i = 1; i < n; i++) a[i] = lower_bound(idx.begin(), idx.end(), alice[i]) - idx.begin(); while(m--){ deal_init_bob(); }}void tree_AC(){ root->fail = NULL; queue<Tree *>que; for(int i = 0; i < root->v.size(); i++){ int x = root->v[i]; Tree *tp = root->next[x]; tp->fail = root; que.push(tp); } while(!que.empty()){ Tree *res = que.front(); que.pop(); for(int i = 0; i < res->v.size(); i++){ int x = res->v[i]; Tree *p = res; while(p->fail != NULL){ p = p->fail; if(p->next[x]){ p = p->next[x]; break; } } res->next[x]->fail = p; que.push(res->next[x]); } }}void work(){ Tree *p = root; for(int i = 1; i < n; i++){ while(p!= root && p->next[a[i]] == NULL) p = p->fail; Tree *res = p->next[a[i]]; if(res == NULL) continue; p = res; while(res != root){ ans += res->cnt; res = res->fail; } } cout << ans << endl;}void debug(){ queue<Tree *>que; que.push(root); while(!que.empty()){ Tree *res = que.front(); que.pop(); for(int i = 0; i < res->v.size(); i++){ int x = res->v[i]; que.push(res->next[x]); } }}int main(){//freopen("in.txt","r",stdin); int T; scanf("%d", &T); while(T--){ root = new Tree(); ans = 0; deal_init(); tree_AC(); work();// debug(); }return 0;}
0 0
- 【HDU】5164 Matching on Array 【AC自动机】
- hdu 5164 Matching on Array AC自动机
- hdu 5164 Matching on Array (奇葩版ac自动机)
- hdu 5164 Matching on Array (用map实现的ac自动机)
- HDU 5164 Matching on Array AC自动机套map
- 【AC自动机】 HDOJ 5164 Matching on Arrayy
- hdu5164 Matching on Array map实现ac自动机
- HDU--3407[String-Matching Automata] AC自动机或kmp
- HDU 3695:Computer Virus on Planet Pandora(AC自动机裸题,数组实现AC自动机)
- HDU 3695 Computer Virus on Planet Pandora(AC自动机)
- HDU 3695 Computer Virus on Planet Pandora(AC自动机)
- hdu 3695 Computer Virus on Planet Pandora AC自动机
- hdu 3695 Computer Virus on Planet Pandora ac自动机
- HDU 3695 Computer Virus on Planet Pandora (AC自动机)
- HDU 3695 Computer Virus on Planet Pandora AC自动机
- 【AC自动机】HDU 3695 Computer Virus on Planet Pandora 裸题
- hdu 3695 Computer Virus on Planet Pandora(AC自动机)
- HDU 3695 Computer Virus on Planet Pandora (AC自动机)
- 记录在2015-01-27
- TiledMap出现小白线
- web请求乱码的机关
- 客户端PureMVC框架与轻型U3D服务器Tnet结合图解
- 树的镜像
- hdu 5164 Matching on Array AC自动机
- 工作总结_2
- playMaker状态机之连击组合技能
- Mongodb:笔记一(安装及基本操作)
- ZOJ 1760 &&POJ1552 Doubles (模拟)
- 基于朴素贝叶斯的花生品种识别
- U3D资源打包与动态加载各种事项与方案
- VLC for iOS 2.3.0
- Oracle 4天实训笔记