Matrix Matcher UVA - 11019 字符串hash或者AC自动机

http://fastvj.rainng.com/problem/UVA-11019

题意很简单不说了;

做法:首先考虑一维字符串如何哈希公式如下:

\sum_{i=1}^{l}{p^{l-i}}s_{i}

然后类比得到二维字符串的哈希公式

\sum_{i=1}^{n} \sum_{j=1}^{m} x^{n-i} y^{m-j} s_{ij}

其他都还差不多的。

时间复杂度不是n*m

#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll hs1=200379;
const ll hs2=196613;
const ll mod=1e9+7;
const int N=1010;
const int M=110;
ll p1[N],p2[N];
ll hs[N][N];
int m,n,x,y;
char s[N][N],t[N][N];
void init()
{
    p1[0]=p2[0]=1;
    for(int i=1;i

AC自动机

这个AC自动机就不怎么好想了,而且效率也不高

方法是利用count[i][j]来记录以(i,j)为左上角,且大小为X,Y的矩形中含有多少个完整行与第二个矩阵对应行完全相同
所以,如果在第一个矩阵的第r行的第c列开始与第二个的第i行匹配,那么count[r-i][c]++;
最后判断是否有count[][]==X;

#include
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=300+10;
const int MAXN=100010;
const int M=1010;
struct node
{
    int next[MAXN][N];
    int fail[MAXN];
    int endd[MAXN];
    int last[MAXN];
    int vt[MAXN][N];
    int vn[MAXN];
    int cnt[M][M];
    int root,l;
    int newnode()
    {
        memset(next[l],0,sizeof(next[l]));
        endd[l]=fail[l]=last[l]=vn[l]=0;
        return l++;
    }
    void init()
    {
        memset(cnt,0,sizeof(cnt));
        l=0;
        root=newnode();
    }
    void Insert(char *s,int id)
    {
        int len=strlen(s);
        int now=root;
        for(int i=0;iqu;
        int now=root;
        for(int i=0;i=vt[j][i])
                    cnt[r-vt[j][i]][c]++;
            print(r,c,last[j]);
        }
    }
    void ffind(int r,char *s)
    {
        int now=root;
        int len=strlen(s);
        for(int i=0;i

 

你可能感兴趣的:(ACM题解)