BZOJ3439 KPM的MC密码

来源:互联网 发布:网络直播项目计划书 编辑:程序博客网 时间:2024/04/29 14:00

传送门
题意:给出n个字符串,对于每一个字符串,输出以他为后缀的串中编号第k小串的编号.
不是很懂为什么网上这道题都是什么主席树,这题明明可以O(N)来实现啊.只需要Hash一下就好了.
对于每一个串的每一个后缀都存一下这个后缀的所在串的编号,因为所有的串的后缀的个数是字符串的总长的,所以,我们只要用Hash表,就能在现行时间内完成整个题目啦!

#include <cstdio>#include <vector>#include <cstring>#define MOD 100007#define MAXN 100005#define LL unsigned long longusing namespace std;vector<int> hd[MAXN];LL h[MAXN];int n; char s[MAXN];struct HashMap {    int adj[MOD], sz, nxt[MAXN]; LL val[MAXN];    int Insert(LL v) {        int u = v % MOD;        for(int i = adj[u]; i; i = nxt[i])            if(val[i] == v) return i;        ++ sz; nxt[sz] = adj[u]; adj[u] = sz; val[sz] = v;        return sz;    }} mp;int main() {    scanf("%d", &n); LL hsh;    for(int i = 1; i <= n; ++ i) {        scanf("%s", s); int l = strlen(s); hsh = 0;        for(int j = l-1; ~j; -- j) {            hsh = hsh * 129 + s[j];            hd[mp.Insert(hsh)].push_back(i);        }        h[i] = hsh;    }    for(int i = 1, k; i <= n; ++ i) {        scanf("%d", &k); int p = mp.Insert(h[i]);        if(hd[p].size() >= k) printf("%d\n", hd[p][k-1]);        else puts("-1");    }    return 0;}
0 0
原创粉丝点击