集训 #5(二维字符串hash学习笔记)

9 篇文章 0 订阅
5 篇文章 0 订阅

https://cn.vjudge.net/contest/239768



A题就很迷,写了剪枝的搜索WA到死,准备拍一下写了个暴力把暴力交了A了。心态炸裂。


C题 给两个集合 从一个集合中挑选至多两个数(可重复选),问能组成多少个另外一个集合中的数。听说是FFT。


H题,二维字符串匹配,学着写白书上的AC自动机,结果因为模板矩阵太大了,T了。然而正解不是优化而是直接写hash,二维hash学习笔记如下。

拓展维数之后应该一维一个base,差点想当然地用的同一个base。这样的话三维hash,想倒是好像就是不太好写。(可能是我不太熟练)然后模板矩阵先压一维(横向压扁),压成一个数组,再次hash成一个数。文本矩阵需要维护一个hash数组,脑补一下,比如说就是一个横行跟模板矩阵大小一样的部分的hash值,这样才能保证向右移动的时候能够O(1)更新一个横行O(n)做完这一列的匹配。 题目在这里:http://codeforces.com/gym/100783/attachments J题
代码这里

//QWsin
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;

typedef unsigned long long ull;

ull baseh=827,bases=1127;

const int maxn=2000+10;

char P[maxn][maxn],M[maxn][maxn];

ull hv[maxn];

int main()
{

    int n,m,x,y;cin>>n>>m>>x>>y;
    rep(i,1,n) scanf("%s",P[i]+1);
    rep(i,1,x) scanf("%s",M[i]+1);

    ull STD=0;
    rep(i,1,n)
    {
        ull tmp=0;
        rep(j,1,m) tmp=tmp*baseh+P[i][j];
        STD=STD*bases+tmp;
    }

    rep(i,1,x) 
    {
        hv[i]=0;
        rep(j,1,m) hv[i]=hv[i]*baseh+M[i][j];
    }

    ull bases_n=1,baseh_m=1;
    rep(i,1,n-1) bases_n=bases_n*bases;
    rep(i,1,m-1) baseh_m=baseh_m*baseh;

    int ans=0;
    rep(j,1,y-m+1) 
    {
        ull cur=0;
        rep(i,1,n-1) cur=cur*bases+hv[i];
        rep(i,n,x)
        {
            cur=(cur-hv[i-n]*bases_n)*bases+hv[i];
            if(cur==STD) 
++ans;
        }

        rep(i,1,x)
  hv[i]=(hv[i]-M[i][j]*baseh_m)*baseh+M[i][j+m];
    }

    cout<<ans<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值