2020牛客暑期多校训练营(第二场)A kmp+hash

题意

对于字符串s,t,定义f(s,t)为s的前缀和t的后缀的最长匹配长度。
给n个字符串,求图片说明

题解

预处理出n个字符串所有后缀的hash值,并记录个数。枚举每一个字符串的所有前缀,求出前缀的hash值,答案加上与前缀相同hash值的后缀个数就行,但是因为要求的是si和sj的最长前后缀长度,例如si=abaa 和 sj=aba匹配,si的前缀a和sj的后缀a匹配,但是最长的是si的前缀aba和sj的后缀aba,所以要减去前面短的不合法的答案。对于以i结尾的前缀字符串,如果前面存在更短的字符串匹配的情况,那么nex[i+1]不为0,res[nex[i+1]-1] -= res[i]。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 7, base = 133, mod = 998244353;
typedef unsigned long long ull;
typedef long long ll;
string s[100005];
int n, nex[maxn];
map<ull,int> mp;
void Hash(string t) {
    ull sum = 0, b = 1;//后缀的计算方法与前缀不同
    for (int i = t.size() - 1; i >= 0; i--, b *= base) {
        sum += b * (t[i] - 'a' + 1);
        mp[sum]++;
    }
}
void get_next(string t) {
    int len = t.size();
    nex[0] = -1;
    int i = 0, j = -1;
    while (i < len) {
        if(j == -1 || t[i] == t[j]) {
            i++; j++;
            nex[i] = j;
        }
        else j = nex[j];
    }
}
int res[maxn];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n;
    ll ans = 0;
    for (int i = 1; i <= n; i++) cin >> s[i], Hash(s[i]);
    for (int i = 1; i <= n; i++) {
        ull sum = 0;
        for (int j = 0; j < s[i].size(); j++) {
            sum = sum * base + (s[i][j] - 'a' + 1);
            res[j] = mp[sum];
        }
        get_next(s[i]);
        for (int j = 0; j < s[i].size(); j++)
            if(nex[j + 1]) res[nex[j + 1] - 1] -= res[j];
        for (int j = 0; j < s[i].size(); j++) {
            ans = (ans + (ll)res[j] * (j + 1) % mod * (j + 1) % mod) % mod;
        }
    }
    cout << ans << endl;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
05-13 16:09
我入职那天分到的mentor是个工作三年的哥们儿,外号杰哥,浙大本硕,技术贼好,人也特别耐心。第一周他手把手带我熟悉项目,下班还带我去公司食堂吃晚饭,跟我讲组里的人际关系、哪个产品好沟通、哪个测试爱挑刺。我当时心里那个踏实啊,心想这mentor是真带我,运气真好。我甚至已经开始幻想转正后跟着他干。周一下午四点多,我正在改一个特别恶心的bug,他飞书突然发我:"小x,跟你说个事儿,我下周一是最后一天,我跳槽了,你之后跟着王哥学。"我当时直接回复了“????”真的以为他在开玩笑。他发了一个尴尬笑的表情,"真的,offer上个月就拿了,一直没说"。我那一瞬间真的不知道说啥。下班的时候我特意去他工位转了一圈,他已经在收拾东西来,看见我笑了一下,说"我请你吃个饭吧"。我们去了公司楼下的麻辣烫。吃饭的时候他跟我说了很多,说大厂这边晋升路径太卷,说他家在外地啊老婆怀孕了啊想离家近点什么的,说新公司虽然小但是给的钱多。我一边吃一边点头,看到一个快到中年研发人的无奈,感觉也看到了未来的我,心里挺不是滋味的。今早上午他飞书里发我一个文档链接,是他这两年攒的项目笔记,模块分工、踩过的坑、谁负责啥都有。他说"这个你留着,遇到问题先看这个再找王哥吧"。说实话,我当时贼感动,工作的这两周,他可能是我在公司里唯一真正把我当回事儿的人了。最后,我想说兄弟们,找实习真的别只看大厂光环,mentor稳定性也是玄学之一。我现在心里有点空,感觉靠山没了
鹿LF:你mt不是才工作三年吗,怎么就中年研发人了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务