简单哈希-2019暑期集训第2次校赛-G.加数字

2019暑期集训第2次校赛-G.加数字

题目描述
给你两个只由小写字母组成的字符串S,T,保证S的长度大于等于T,现在你必须删除T串中一个字符,使得T串变成S串的子串,输出删除的位置,如果有多个位置合法,输出最小的那个,如果没有合法的位置,输出-1
输入描述:
第一行输入字符串S(2 <= |S| <= 3e5)

第二行输入字符串T(2 <= |T| <= S)
输出描述:
输出一个数
示例1
输入
复制
aaaab
aabaa
输出
复制
3
示例2
输入
复制
aaaa
aaa
输出
复制
1
示例3
输入
复制
abcd
xyz
输出
复制
-1
思路
简单哈希,把s串中连续长度为len_t-1的子串转化成相应数值,存到map里;再把t串中例举拿掉每个字符,把拿掉一个字符的子串转化为数值,若map中存在该值则找到合法答案了。
题解

#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+10;
char s[maxn],t[maxn];
long long  base[3]={0,23,29},mod[3]={0,100000000+7,100000000+9},h[3][maxn],f[3][maxn];
map<long long,int >mp_1,mp_2;
long long ksm(long long res,long long cnt,long long mo)
{
    long long  sum=1;
    while(cnt>0)
    {
        if(cnt&1)sum=(sum*res)%mo;
        res=(res*res)%mo;
        cnt>>=1;
    }
    return sum;
}
int main()
{
	//memset(h,0,sizeof(h));
	//memset(f,0,sizeof(f));
    scanf("%s%s",s+1,t+1);
    int len_s=strlen(s+1);
    int len_t=strlen(t+1);

    for(int i=1;i<=len_s;i++)
    {
    	for(int k=1;k<=2;k++)
    	h[k][i]=(h[k][i-1]*base[k]+s[i]-'a'+1)%mod[k];
        
    }
    long long res[3];
    for(int i=len_t-1;i<=len_s;i++)
    {
    	for(int k=1;k<=2;k++)
    	res[k]=(h[k][i]-h[k][i-len_t+1]*ksm(base[k],len_t-1,mod[k])%mod[k]+mod[k])%mod[k];
    	mp_1[res[1]]=1;
    	mp_2[res[2]]=1;
    	
	}
	
    for(int i=1;i<=len_t;i++)
    {
        for(int k=1;k<=2;k++)
         f[k][i]=(f[k][i-1]*base[k]+t[i]-'a'+1)%mod[k];
    }
    
    
    for(int i=1;i<=len_t;i++)
    {
        for(int k=1;k<=2;k++)
            res[k]=(f[k][len_t]-f[k][i]*ksm(base[k],len_t-i,mod[k])%mod[k]
			        +f[k][i-1]*ksm(base[k],len_t-i,mod[k])%mod[k]+mod[k])%mod[k];
        if(mp_1[res[1]]==1&&mp_2[res[2]]==1)
        {
            cout<<i;
            return 0;
        }
    }
            
    cout<<-1<<endl;  
        
    

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值