zoukankan      html  css  js  c++  java
  • [uva][4657][Top 10]

    题目:http://livearchive.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2658

    ac自动机。先把单词按照题意排序,把询问串建成trie树,然后按照单词顺序进行查询,注意好结果保存,询问串可能会有重复。

    View Code
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    #define clr(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    const int N = 1000000+10;
    const int M = 10001 * 50;
    const int ch = 26;
    int sw[128];
    int trie[M][ch+1], top, n, q[M], bg, ed, fail[M];
    bool vis[M];
    char str[N];
    vector<int>ans[N], tim[N];
    struct acstr
    {
        int id;
        string s;
        void get(int i){ id=i; gets(str); s=str;}
        bool operator < (const acstr& a)const{
            if (s.length()==a.s.length()){
                if (s == a.s)return id < a.id;
                return s < a.s;
            }
            return s.length() < a.s.length();
        }
    }buf[20010];
    
    void init(){
        top = 1; clr(trie[0], 0);
        for (char i='a', j=0; i<='z'; i++, j++)
            sw[i] = j;
    }
    void ins(char *s, int rank){
        int rt, nxt;
        for (rt=0; *s; rt=nxt, s++){
            nxt = trie[rt][sw[*s]];
            if (nxt == 0){
                clr(trie[top], 0); trie[rt][sw[*s]]=nxt=top++;
            }
        }
        tim[rt].push_back(rank);   // 保存该点id,不能直接覆盖,可能会有重复
    }
    void makefail(){
        int u, v;
        fail[0] = bg = ed = 0;
        for (int i=0; i<ch; i++)
            if (q[ed] = trie[0][i])
                fail[q[ed++]] = 0;
        while (bg < ed){
            u = q[bg++];
            for (int i=0; i<ch; i++){
                if (v = trie[u][i])
                    q[ed++]=v, fail[v]=trie[fail[u]][i];
                else
                    trie[u][i] = trie[fail[u]][i];
            }
        }
    }
    void ac(const char *s, int id){
        clr(vis, 0);
        for (int i=0; *s; s++){
            i=trie[i][sw[*s]];
            for (int j=i,v; j; j=fail[j]){
                for (int k=0; k<tim[j].size(); k++){  
                    v=tim[j][k];
                    if(vis[v])continue;
                    vis[v] = true;
                    if (ans[v].size()<10)ans[v].push_back(id);
                }
            }
        }
    }
    char tmp[20010];
    int main(){
        //freopen("D:/a.txt", "r", stdin);
        int n, q;
        while (~scanf("%d", &n)){
            init(); getchar();
            for (int i=1; i<=n; i++)
                buf[i].get(i);
            sort(buf+1, buf+1+n);
            scanf("%d", &q);
            for (int i=1; i<=q; i++){
                scanf("%s", tmp); ins(tmp, i);
            }
            makefail();
            for (int i=1; i<=n; i++) ac(buf[i].s.c_str(),buf[i].id);
            for (int i=1; i<=q; i++){
                if (ans[i].size()==0)printf("-1\n");
                else for (int j=0; j<ans[i].size(); j++)
                    printf("%d%c", ans[i][j], j==ans[i].size()-1?'\n':' ');
            }
        }
        return 0;
    }
  • 相关阅读:
    Drupal 7 中文安装教程
    苹果之硬盘启动安装
    STP详解
    RedHat Install
    Linux密码更改
    win8.1开启虚拟wifi
    跳过安装密钥安装系统
    虚拟机中Linux安装Tools
    桌面虚拟化之XenDesktop7
    桌面虚拟化之部署DDC-5.6
  • 原文地址:https://www.cnblogs.com/nigel0913/p/2592196.html
Copyright © 2011-2022 走看看