CF D. DZY Loves Strings(字符串hash 暴力)

来源:互联网 发布:淘宝联盟红包很无耻 编辑:程序博客网 时间:2024/05/22 03:39

题目链接
题意:给出一个字符串,然后有q次询问,在字符串中找出最短的字串使其包涵询问的2个串。

询问的串长度不大于4,暴力预处理一下,每个长度的子串在原串中的位置。然后在暴力计算,这里暴力计算也是有技巧的,因为预处理的数组是有序的所以这里暴力要使用线性的方法,具体是正着先找小于的,逆着找大于的。每次不要从头开始,因为有序,直接继续。

//#include<bits/stdc++.h>#include<iostream>#include<cstdio>#include<algorithm>#include<vector>#include<queue>#include<stack>#include<cstring>#include<set>#include<map>#include<string>#include<cassert>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))#define fastIO ios::sync_with_stdio(false);cin.tie(0);#define LL unsigned long long#define pb push_back#define gcd __gcd#define For(i,j,k) for(int i=(j);i<=k;i++)#define lowbit(i) (i&(-i))#define _(x) printf("%d\n",x)typedef vector<LL> vec;typedef pair<int,int> PI;const double EPS = 1e-8;const int maxn = 2e6+10;const int inf  = 1 << 28;int n,m,x;int p = 31;char str[maxn/10];char s[2][maxn];vector<int> v[maxn];map<pair<int,int>,int> mp;int main(){    scanf("%s",str);    int len = strlen(str);    for(int i=1;i<=4;i++){        for(int j=0;j+i-1<len;j++){            int t=0;            for(int k=j;k<i+j;k++){                t=t*p+(str[k]-'a')+11;            }            v[t].pb(j);        }    }    int q;scanf("%d",&q);    while(q--){        scanf("%s%s",&s[0],&s[1]);        int t1=0,t2=0;        int n=strlen(s[0]),m=strlen(s[1]);        for(int i=0;i<n;i++)t1=t1*p+(s[0][i]-'a')+11;        for(int i=0;i<m;i++)t2=t2*p+(s[1][i]-'a')+11;        if(mp[make_pair(t1,t2)]!=0){            printf("%d\n",mp[make_pair(t1,t2)]);            continue;        }        int ans=1<<27;        //线性的暴力查找!        for(int i=0,j=0;i<v[t1].size();i++){            while(j<v[t2].size()&&v[t2][j]<v[t1][i])j++;            if(j>=v[t2].size())break;            ans = min(ans, max(v[t1][i]+n,v[t2][j]+m)-min(v[t1][i],v[t2][j]));        }        for(int i=v[t1].size()-1,j=v[t2].size()-1;i>=0;i--){            while(j>=0&&v[t2][j]>v[t1][i])j--;            if(j<0)break;            ans = min(ans, max(v[t1][i]+n,v[t2][j]+m)-min(v[t1][i],v[t2][j]));        }        if(ans == (1<<27))ans=-1;        mp[make_pair(t1,t2)]=ans;        mp[make_pair(t2,t1)]=ans;        printf("%d\n",ans);    }    return 0;}
0 0