2019ICPC 上海網絡賽 G題 Substring(哈希)

題意:

給了一個母串S, 每次循環給了一個模板串,問模板串在母 串中“匹配”了多少次?“匹配”的意思就是首字母和尾字母一樣, 中間字母順序可以換。

題解:

字符串hash.我們將詢問字符串的首尾特殊hash,然後將詢問串的長度存入到vector裏面。

然後遍歷一遍原串,將所有是詢問串長度的子串的哈希值插入到vecor並排序,然後對於該詢問,我們只要用lower_bound和upper_bound查找有多少哈希值等於我的就行了,記錄答案,最後輸出答案。

 

參考代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define pb push_back
#define base 1000039
#define pii pair<int,int>
#define pil pair<int,ll>
#define mkp make_pair
#define RI register int
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
const int maxm=2e4+10;
int T,Q,ans[maxm];
char s1[maxn<<1],s2[maxn];
ull p[30],x[maxm],y[maxn];
vector<int> vec[maxn];
inline int idx(char ch){return ch-'a'+1;}
inline void preHash()
{
    p[0]=1;
    for(RI i=1;i<30;++i) 
        p[i]=p[i-1]*base;
}
inline void work()
{
    for(RI i=1;i<=Q;++i)
    {
        scanf("%s",s2+1);
        int len=strlen(s2+1);
        x[i]=idx(s2[1])*p[28]+idx(s2[len])*p[29];
        for(RI j=2;j<=len-1;++j) x[i]+=p[idx(s2[j])];
        vec[len].pb(i);
    }    
}
inline void solve()
{
    int len=strlen(s1+1);
    for(RI i=1;i<=len;++i)
    {
        int siz=vec[i].size();
        if(!siz) continue;
        ull pre=0; int cnt=0;
        for(RI j=1;j<i;++j) pre=pre+p[idx(s1[j])];
        for(RI j=i;j<=len;++j)
        {
            pre=pre+p[idx(s1[j])];
            if(j!=i) pre-=p[idx(s1[j-i])];
            ull res=pre-p[idx(s1[j])]-p[idx(s1[j-i+1])]+(idx(s1[j-i+1]))*p[28]+(idx(s1[j]))*p[29];
            y[++cnt]=res;
        }
        sort(y+1,y+1+cnt);
        for(RI j=0,siz=vec[i].size();j<siz;++j)
        {
            int dn=lower_bound(y+1,y+1+cnt,x[vec[i][j]])-y;
            int up=upper_bound(y+1,y+1+cnt,x[vec[i][j]])-y;
            ans[vec[i][j]]=up-dn;
        }
    }    
}
int main()
{
    preHash(); 
    scanf("%d",&T); 
    while(T--)
    {
        for(RI i=0;i<maxn;++i) vec[i].clear();
        scanf("%s%d",s1+1,&Q);
        work(); solve();
        for(RI i=1;i<=Q;++i) printf("%d\n",ans[i]);
    }
    return 0;

}
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章