Codeforces 114D

题目链接  

题意

问在string t中有多少个以string begin为开头,string end为结尾的不相同的连续子串

题解

刚开始的时候因为没学过字符串hash,所以直接把string开了一个set存起来,然后tle满天飞。之后就学了字符串hash,在后面的点照样tle。无奈去膜别人的代码,发现别人不用set,而用unordered_set。去查了一下c++ referenc,发现unordered_set是用hash表储存的,set是用红黑树储存的。在面对数值相差很大的hash值的时候,很明显unordered_set要快很多。。学习了。

#include<unordered_set>
#include<string>
#include<iostream>
#define N 2010
#define LL long long

using namespace std;

string s,a,b;
bool I[N],II[N];
unordered_set<LL> ans;

int main(){
    cin>>s>>a>>b;
    int n=s.size(),aa=a.size(),bb=b.size();
    int longn=aa>bb? aa:bb;
    for(int i=0;i<n;++i){
        if(s.substr(i,aa)==a) I[i]=1;
        if(s.substr(i,bb)==b) II[bb-1+i]=1;
    }
    LL hashd;
    for(int i=0;i<n;++i){
        if(I[i]){
            hashd=0;
            for(int j=i;j<n;++j){
                hashd=hashd*2333+s[j];
                if(II[j]&&j-i+1>=longn) ans.insert(hashd);
            }
        }
    }
    cout<<ans.size();
    return 0;
}

附加内容

字符串hash用代码来表示非常简洁,写出来之后直接意会一下就可以了(其实是语文老师下线语言无法组织)。

char s[50];//准备hash的字符串
long long hashd=0;//hash值
int seed;//hash用的种子

for(int i=0;s[i];++i) hashd=hashd*seed+s[i];

猜你喜欢

转载自www.cnblogs.com/jiaangk/p/9203812.html