传送门
题意:给出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;
}