求分析哈希做法复杂度
查看原帖
求分析哈希做法复杂度
759274
Stevehim楼主2023/11/24 11:48
#include <bits/stdc++.h>
#define maxn 2001000
#define maxm 200010
#define SEED 13331
#define re register
using namespace std;
typedef unsigned long long ull;
char target[maxn], str[maxm];
int l[maxm], r[maxm];
ull p[maxn], sum1[maxn], tmp[maxm];
vector<int> m[26][26]; //匹配
vector<ull> sum;
inline ull calc1(int l,int r){return sum1[r] - sum1[l - 1] * p[r - l + 1];}
int n, ans[maxn], tlen, slen[maxn], ma;

int main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    p[0] = 1;
    for(re int i = 1; i < maxn; i++) p[i] = p[i - 1] * SEED;
    cin >> n;
    ma = 0;
    for(re int i = 1; i <= n; i++){
        cin >> (str + 1), slen[i] = strlen(str + 1);
        for(int j = 1; j <= slen[i]; j++) tmp[j] = tmp[j - 1] * SEED + str[j] - 'a';
        sum.push_back(tmp[slen[i]]);
        l[i] = str[1] - 'a', r[i] = str[2] - 'a';
    }
    cin >> (target + 1);
    tlen = strlen(target + 1);
    for(re int i = 1; i <= tlen; i++) sum1[i] = sum1[i - 1] * SEED + target[i] - 'a';
    for(re int i = 0; i < 26; i++) for(int j = 0; j < 26; j++) m[i][j].clear();
    for(re int i = 1,j = 2; j <= tlen; j++, i++) m[target[i] - 'a'][target[j] - 'a'].push_back(i); //预处理一下
    for(re int i = 1; i <= n; i++){
        if(slen[i] == 1){
            for(re int j = 1; j <= tlen; j++) if(target[j] - 'a' == l[i]) ans[i]++;
            continue;
        }
        if(m[l[i]][r[i]].size() == 0) continue;
        for(re int u = 0; u < m[l[i]][r[i]].size(); u++){
            int st = m[l[i]][r[i]][u];
            if(calc1(st, st + slen[i] - 1) == sum[i - 1]){ans[i]++;} //匹配到了,退出,不然下一个
        }
    }
    for(int i = 1; i <= n; i++) cout << ans[i] << '\n';
    return 0;
}
2023/11/24 11:48
加载中...