bunoj 34990(hash)

传送门:Justice String

题意:有两个串A,B,问是否存在A的一个子串S,S和B的长度相等,最多有2个字符不同。如果有多个,输出其实下标最小S的下标,没有输出-1。

分析:从A每个位置开始找最长公共前缀,如果最长公共前缀长度不大于lenb,继续从下一次位置开始找,至多找两次,如果一直找不到就算不存在。

#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <cmath>
#include <algorithm>
#define LL long long
#define N 100010
using namespace std;
const LL mod=1000000007ll;
const LL SEED=131;
char a[N],b[N];
int lena,lenb;
unsigned LL hha[N],hhb[N];
unsigned LL p[N];
void init()
{
    hha[0]=a[0];
    hhb[0]=b[0];
    for(int i=1;i<lena;i++)
    {
        hha[i]=hha[i-1]*SEED+a[i];
    }
    for(int i=1;i<lenb;i++)
    {
        hhb[i]=hhb[i-1]*SEED+b[i];
    }
}
LL calc(int x,int len,unsigned LL f[])
{
    return f[x+len-1]-f[x-1]*p[len];
}
int lcp(int pa,int pb)
{
    int l=0,r=lenb-pb,ans;
    while(l<=r)
    {
        int m=(l+r)>>1;
        if(calc(pa,m,hha)==calc(pb,m,hhb))
            l=m+1,ans=m;
        else r=m-1;
    }
    return ans;
}
int main()
{
    int T,cas=1;
    p[0]=1ll;
    for(int i=1;i<N;i++)p[i]=p[i-1]*SEED;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",a,b);
        lena=strlen(a);
        lenb=strlen(b);
        init();
        int ans=-1;
        for(int i=0;i<=lena-lenb;i++)
        {
            int num=0;
            num+=lcp(i+num,num);
            if(num>=lenb)
            {
                ans=i;break;
            }
            num++;
            if(num>=lenb)
            {
                ans=i;break;
            }
            num+=lcp(i+num,num);
            if(num>=lenb)
            {
                ans=i;break;
            }
            num++;
            if(num>=lenb)
            {
                ans=i;break;
            }
            num+=lcp(i+num,num);
            if(num>=lenb)
            {
                ans=i;break;
            }
        }
        printf("Case #%d: %d\n",cas++,ans);
    }
}

时间: 2024-07-30 17:01:55

bunoj 34990(hash)的相关文章

哈希(Hash)与加密(Encrypt)相关内容

1.哈希(Hash)与加密(Encrypt)的区别 哈希(Hash)是将目标文本转换成具有相同长度的.不可逆的杂凑字符串(或叫做消息摘要),而加密(Encrypt)是将目标文本转换成具有不同长度的.可逆的密文. i.哈希算法往往被设计成生成具有相同长度的文本,而加密算法生成的文本长度与明文本身的长度有关. 例:设我们有两段文本:"Microsoft"和"Google".两者使用某种哈希算法得到的结果分别为:"140864078AECA1C7C35B4BEB

hdu 4886 TIANKENG’s restaurant(Ⅱ) (hash)

题目大意: 求出在文本串中第一个没出现的字典序最小的串.. 思路分析: 开始的时候 用后缀数组写,然后根据sa的有序性.你就可以知道哪个串没有出现了. 但是题目卡了倍增哦... 自习想一想的话,我们用 sa 数组,也就是想知道这个串有没有出现过,也就是判断重复,却浪费了  O (n * lg n)... 判断重复为什么没想到hash . 把每一个长度的子串都hash 出来,用八进制表示,这样的话就可以得到一个递增的hash值. 将之存入hash 数组.找到第一个空的hash的下标,就是第一个没出

HDU 4821 (hash)

这道题最重要的不仅是hash这种算法,更要学会利用好STL中的<map>才行. 将连续的L个字符经过hash赋值,最后线性判断.其中的判断步骤用到了map的插入特性. #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <map> using namespace std; #define maxn 500010 #

poj 1200 (hash)

Crazy Search Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23168   Accepted: 6513 Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a gi

HDU 1880 魔咒词典 (Hash)

魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16641    Accepted Submission(s): 3916 Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所

AcWing:138. 兔子与兔子(Hash)

很久很久以前,森林里住着一群兔子. 有一天,兔子们想要研究自己的 DNA 序列. 我们首先选取一个好长好长的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 个小写英文字母). 然后我们每次选择两个区间,询问如果用两个区间里的 DNA 序列分别生产出来两只兔子,这两个兔子是否一模一样. 注意两个兔子一模一样只可能是他们的 DNA 序列一模一样. 输入格式 第一行输入一个 DNA 字符串 S. 第二行一个数字 m,表示 m 次询问. 接下来 m 行,每行四个数字 l1,r1,l2,r2

哈希表(hash)详解

 哈希表结构讲解: 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. 记录的存储位置 = function(关键字) 这里的对应关系function称为散列函数,又称为哈希(Hash函数),采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table). 哈希表hashta

互斥的数(hash)

1553 互斥的数 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 有这样的一个集合,集合中的元素个数由给定的N决定,集合的元素为N个不同的正整数,一旦集合中的两个数x,y满足y = P*x,那么就认为x,y这两个数是互斥的,现在想知道给定的一个集合的最大子集满足两两之间不互斥. 输入描述 Input Description 输入有多组数据,每组第一行给定两个数N和P(1<=N<=10^5, 1<=P<=10^9)

Hdu 3682 To Be an Dream Architect(Hash)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3682 思路:Hash.对于每个(x,y,z)坐标的立方体,映射为x*n*n+y*n+z,判断有多少个不同数字即为删去立方体个数. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; vector<int