zoukankan      html  css  js  c++  java
  • 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
    ",tans[i]);
        }
        return 0;
    }

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

     +本文作者:luyouqi233。               +

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

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

  • 相关阅读:
    复杂json对应的实体类定义
    Hbase 根据rowkey批量读写
    Spark 分组聚合转Map 的方式
    idea本地连接访问hadoop集群的方法
    新版supperset连接druid数据源设置
    使用jdbc java 连接 sqlserver 2008数据库 需要注意的事项
    关于CrystalQuartz设置Cron匹配的时区问题~
    VS2010连接远程TFS2012项目问题
    关于ASP.NET SignalR的Group使用
    关于CodeFrist下EntityFramework5.0及其最新版本中枚举的使用
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/15133827.html
Copyright © 2011-2022 走看看