zoukankan      html  css  js  c++  java
  • AcWing 160. 匹配统计 (哈希+二分) 打卡

    阿轩在纸上写了两个字符串,分别记为A和B。

    利用在数据结构与算法课上学到的知识,他很容易地求出了“字符串A从任意位置开始的后缀子串”与“字符串B”匹配的长度。

    不过阿轩是一个勤学好问的同学,他向你提出了Q个问题:

    在每个问题中,他给定你一个整数x,请你告诉他有多少个位置,满足“字符串A从该位置开始的后缀子串”与B匹配的长度恰好为x。

    例如:A=aabcde,B=ab,则A有aabcde、abcde、bcde、cde、de、e这6个后缀子串,它们与B=ab的匹配长度分别是1、2、0、0、0、0。

    因此A有4个位置与B的匹配长度恰好为0,有1个位置的匹配长度恰好为1,有1个位置的匹配长度恰好为2。

    输入格式

    第一行输入三个整数N,M,Q,分别表示A串长度、B串长度、问题个数。

    第二行输入字符串A,第三行输入字符串B。

    接下来Q行每行输入1个整数x,表示一个问题。

    输出格式

    输出共Q行,依次表示每个问题的答案。

    数据范围

    1N,M,Q,x2000001≤N,M,Q,x≤200000

    输入样例:

    6 2 5
    aabcde
    ab
    0
    1
    2
    3
    4
    

    输出样例:

    4
    1
    1
    0
    0


    题意:要你求原来的字符串的所有起点位置去匹配第二个字符串能匹配多少个字符,然后我们再输入x,看正好匹配长度为x的起点位置有多少个
    思路:这个我们看能匹配多少个字符,这里其实匹配也就相当于相等,判断字符串相等自然用哈希,让我们我们又不知道他匹配的长度是多少,我们就需要枚举,既然可以枚举我们就可以优化成二分
    求出两个字符串的哈希,然后预处理每个位置,二分长度用map存下来即可
    #include<bits/stdc++.h>
    #define maxn 200005
    #define mod 1000000007
    using namespace std;
    typedef long long ll; 
    typedef unsigned long long ull;
    ll n,m,q;
    char s1[maxn],s2[maxn];
    ull dp1[maxn],dp2[maxn],f[maxn];
    map<ll,ll> mp;
    void hash_code(){
        f[0]=1;
        for(int i=1;i<=n;i++){
            dp1[i]=dp1[i-1]*131+s1[i]-'a'+1;
            f[i]=f[i-1]*131;
        }
        for(int i=1;i<=m;i++){
            dp2[i]=dp2[i-1]*131+s2[i]-'a'+1;
        }
    }
    int check(ll dex,ll len){
        if(dp1[dex+len-1]-dp1[dex-1]*f[len]==dp2[len]){
            return 1;
        }
        return 0;
    }
    int main(){
        cin>>n>>m>>q;
        cin>>s1+1>>s2+1;
        hash_code();
        for(ll i=1;i<=n;i++){
            ll l=0,r=m+1,mn=0;
            while(l<r){
                ll mid=(l+r)/2;
                if(check(i,mid)){
                    mn=mid;
                    l=mid+1;
                }
                else{
                    r=mid;
                }
            }
            mp[mn]++;
        //    cout<<mn<<"
    ";
        }
        int x;
        for(int i=0;i<q;i++){
            cin>>x;
            cout<<mp[x]<<"
    ";
        } 
    } 
    
    /*
    6 2 5
    aabcde
    ab
    0
    1
    2
    3
    4
    5
    */
     
  • 相关阅读:
    各位信息技术男,你们在折腾什么?
    在 C# 中使用 P/Invoke 调用 Mupdf 函数库显示 PDF 文档
    用PDF补丁丁一分钟倒排逆页序PDF文档
    简单解决“ORA27100: shared memory realm already exists”的问题
    用PDF补丁丁一分钟批量更改PDF书签的默认展开或关闭状态
    TImageList 图标更新通知方案
    常用注释
    delphi XE 下打开内存泄漏调试功能
    炎炎夏日需要一个清凉的地 自制水冷系统(十一 指尖的思绪之程序篇)
    炎炎夏日需要一个清凉的地 自制水冷系统(十 高温作业:焊接)
  • 原文地址:https://www.cnblogs.com/Lis-/p/10935834.html
Copyright © 2011-2022 走看看