HDU7064:Singing Superstar——题解

https://acm.hdu.edu.cn/showproblem.php?pid=7064

问子串在母串中不重叠地出现最多多少次。

正解哈希,子串长度只有30就直接枚举母串中所有长度30以里的串哈希然后乱搞一通就行。

但是这题数据范围给的很离谱,给了其他做法可乘之机。如果我们**处理掉所有的重复的字符串**(不判重很容易卡)的话,不难发现数据拉满的最坏情况下平均一个子串长度才4,因此建立Trie高度不会很高(或者说,可能会有几条链很长但是整体很短),因此暴力跑Trie也能过。

(这题最后就剩1h不到了因此急了瞎98交了14发……虽然其中很大程度是在二分Trie树该开多大我一直怀疑它数据没改QAQ)

#include<map>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int M=4e6+5;
struct Trie{
    map<int,int>a;
    vector<int>ed;
}tr[M];
int cnt,n,ans[N],tans[N],where[N],len[N];
string s,bs;
void insert(int id){
    int m=len[id],now=0;
    for(int i=0;i<m;i++){
        int c=s[i]-'a';
        if(!tr[now].a[c])tr[now].a[c]=++cnt;
        now=tr[now].a[c];
    }
    tr[now].ed.push_back(id);
    return;
}
int tot;
map<string,int>mp;
vector<int>in[N];
void init(){
    for(int i=0;i<=cnt;i++){
        tr[i].a.clear();
        tr[i].ed.clear();
    }
    for(int i=1;i<=tot;i++){
        ans[i]=0;
        in[i].clear();
    }
    mp.clear();
    cnt=tot=0;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        init();
        cin>>bs>>n;
        for(int i=1;i<=n;i++){
            cin>>s;
            if(!mp[s]){
                mp[s]=++tot;
                len[tot]=s.length();
                insert(mp[s]);
                where[tot]=-len[tot];
            }
            in[mp[s]].push_back(i);
        }
        int m=bs.length();
        for(int i=0;i<m;i++){
            int now=0;
            for(int j=i;j<m;j++){
                if(!tr[now].a.count(bs[j]-'a'))break;
                now=tr[now].a[bs[j]-'a'];
                for(int k=0;k<tr[now].ed.size();k++){
                    int id=tr[now].ed[k];
                    if(where[id]+len[id]<=i){
                        where[id]=i;
                        ans[id]++;
                    }
                }
            }
        }
        for(int i=1;i<=tot;i++){
            for(int j=0;j<in[i].size();j++){
                tans[in[i][j]]=ans[i];
            }
        }
        for(int i=1;i<=n;i++)printf("%d\n",tans[i]);
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2021-08-12 17:25  luyouqi233  阅读(107)  评论(0编辑  收藏  举报