0
点赞
收藏
分享

微信扫一扫

2021“MINIEYE杯”中国大学生算法设计超级联赛(8)- 1009(Singing Superstar)

补题链接:​​https://acm.hdu.edu.cn/showproblem.php?pid=7064​​

​板子题:字符串hash​

​code​

#include<iostream>
#include<algorithm>
#include <cstring>
#include <unordered_map>

using namespace std;

// 2^64,让其自然溢出,相当于对2^64取mod
typedef unsigned long long ULL;

// P(进制数)一般取131/13331
const int N = 100010, P = 131;

int n, m;
char str[N];
ULL h[N], p[N];

// 求[l, r]区间的字符串的hash值
ULL get(int l, int r){

// 1 ~ (l - 1)(从高位到低位)
// 1 ~ r (从高位到低位)
// L ~ R (相当于把h[l - 1]左移动(r - (l - 1))位, 然后用h[r]减去)
return h[r] - h[l - 1] * p[r - l + 1];
}

void solve(){

scanf("%s", str + 1);

n = strlen(str + 1);

unordered_map<ULL, int> cnt;
unordered_map<ULL, int> lst;

p[0] = 1;
for(int i = 1; i <= n; i++){

h[i] = h[i - 1] * P + str[i];
p[i] = p[i - 1] * P;
}

scanf("%d", &m);

char chs[33];
ULL a[m];

for (int i = 1; i <= m; ++i) {

scanf("%s", chs + 1);

ULL hs = 0;
for (int i = 1; chs[i]; ++i) {
hs = hs * P + chs[i];
}

a[i] = hs;
cnt[hs] = 0;
lst[hs] = 0;
}

for (int len = 1; len <= 30; ++len) {
for (int i = 1; i + len - 1 <= n; ++i) {

ULL hs = get(i, i + len - 1);
if(cnt.count(hs) && lst[hs] <= i){

lst[hs] = i + len;
cnt[hs]++;
}
}
}

for (int i = 1; i <= m; ++i) {

printf("%d\n", cnt[a[i]]);
}
}

int main(){

int t;

scanf("%d", &t);

while(t--) solve();

return 0;
}


举报

相关推荐

0 条评论