BZOJ3439 KPM的MC密码

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

#include <cstdio>
#include <vector>
#include <cstring>
#define MOD 100007
#define MAXN 100005
#define LL unsigned long long
using 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值