• 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
    ",ans[i]);
        }
        return 0;
    
    }
    View Code
  • 相关阅读:
    USB 描述符详细解析,来自老外网站,比协议描述清晰
    linux那些事儿之我是usb
    usb开源项目
    Quartus II 增量编译
    Quartus II 与 Modelsim 联调【转】
    Matlab语法
    RC上电复位时间计算
    Quartus 编译错误
    UltraEdit 所有快捷键 说明
    [转载]BT656/BT601/BT1120协议
  • 原文地址:https://www.cnblogs.com/csushl/p/11558183.html
Copyright © 2020-2023  润新知