【AC自动机】 HDOJ 5164 Matching on Arrayy

先对原串和匹配串相连做商,然后建立AC自动机做匹配就行了,注意用map存边。。。

#include <iostream>
#include <queue> 
#include <stack> 
#include <map> 
#include <set> 
#include <bitset> 
#include <cstdio> 
#include <algorithm> 
#include <cstring> 
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 100005
#define maxm 1000005
#define eps 1e-10
#define mod 1000000007
#define INF 0xi3f3f3f3f
#define PI (acos(-1.0))
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid 
#define rson o<<1 | 1, mid+1, R
#define pii pair<int, int>
//#pragma comment(linker, "/STACK:16777216")
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
// head

struct fra
{
	int a, b;
	fra() {}
	fra(int a, int b) : a(a), b(b) {}
	bool operator < (const fra t) const {
		if(t.a == a) return b > t.b;
		else return a > t.a;
	}
};

struct node
{
	int key;
	node *fail;
	map<fra, node*> next;
};
node *root, *now;
node pool[maxm], *tail;
map<fra, node*>::iterator it;
queue<node*> q;
int s[maxn], a[maxn];
int n, m;
LL ans;

void init()
{
	tail = pool;
	tail->key = 0;
	tail->fail = NULL;
	tail->next.clear();
	root = tail++;
	ans = 0;
	s[0] = 1;
}

node* newnode()
{
	tail->key = 0;
	tail->fail = NULL;
	tail->next.clear();
	return tail++;
}

void insert(int len)
{
	now = root;
	for(int i = 1; i <= len; i++) {
		fra t = fra(s[i] / __gcd(s[i], s[i-1]), s[i-1] / __gcd(s[i], s[i-1]));
		if(!now->next.count(t)) now->next[t] = newnode();
		now = now->next[t];
	}
	now->key++;
}
void build()
{
	now = root;
	for(it = now->next.begin(); it != now->next.end(); it++) {
		(*it).second->fail = root;
		q.push((*it).second);
	}
	while(!q.empty()) {
		now = q.front();
		q.pop();
		now->key += now->fail->key;
		for(it = now->next.begin(); it != now->next.end(); it++) {
			node *p = now->fail;
			while(p) {
				if(p->next.count((*it).first)) {
					now->next[(*it).first]->fail = p->next[(*it).first];
					break;
				}
				p = p->fail;
			}
			if(!p) now->next[(*it).first]->fail = root;
			q.push(now->next[(*it).first]);
		}
	}
}

LL query(int len)
{
	now = root;
	for(int i = 1; i <= len; i++) {
		fra t = fra(s[i] / __gcd(s[i], s[i-1]), s[i-1] / __gcd(s[i], s[i-1]));
		while(now != root && !now->next.count(t)) now = now->fail;
		if(!now->next.count(t)) continue;
		now = now->next[t];
		ans += now->key;
	}
	return ans;
}

void read()
{
	int k;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i++) scanf("%d", &a[i]);
	while(m--) {
		scanf("%d", &k);
		for(int i = 0; i < k; i++) scanf("%d", &s[i]);
		if(k > 1) insert(k - 1);
		else ans += n;
	}
	for(int i = 0; i < n; i++) s[i] = a[i];
}

void work()
{
	build();
	printf("%I64d\n", query(n - 1));
}

int main(void)
{
	int _;
	while(scanf("%d", &_)!=EOF) {
		while(_--) {
			init();
			read();
			work();
		}
	}
	
	
	return 0;
}


你可能感兴趣的:(AC自动机,BestCoder)