2020牛客暑期多校训练营(第二场)

A All with Pairs

首先:得感谢我的队友,因为我之前在赶课设,完全没有去补题,神雕侠侣,我是其中的雕

题意:将n个字符串输入,然后求s[i]的前缀和s[j]的后缀匹配的最大长度,平方,求和

思考:补这道题可谓是经历了九九八十一难,显示自己一直在怀疑自己题目意思是否看懂,结果发现自己的确没有理解题意,然后多亏了群巨暮雨忽来的帮助,我理解了题目的意思,只有确认了,自己字符串操作已经是傻逼了,只能重新把之前的字符串的KMP,hash,trie和AC自动机全部重新看一遍,看前面三个一小时,AC自动机看了一上午都没有整明白,真的是废了(之前也没有整明白)
整完之后AC自动机整了半天,自己的思路是将所有的字符串进行建立trie图,注意以为节点建立fail,然后不断一个一个枚举最大长度,结论:还是不行
最后再刘小哥哥的思路之下开拓了,直接就是将所以的字符串进行hash,然后不断的进行存入map数组中,之后统计每个字符串的前缀在map中出现的次数。

因为考虑到去重,需要将每个字符串的next数组给求出来,然后减去就可以了,代码如下(参考的,之后自己搞一搞AC自动机做法,群巨推荐),为了赶时间,临时补一下:

#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#define rep(i,a,b) for(int i = a; i <= b ; i ++ )
#define pre(i,a,b) for(int i = b ; i >= a ; i --)
#define ll long long
#define inf 0x3f3f3f3f
#define ull unsigned long long
#define ios ios::sync_with_stdio(false),cin.tie(0)
using namespace std;
typedef pair<int,int> PII ;
const int N=2e6+10,mod=998244353,p=233;

string s[N];
string T;
ull Hash[N];
ull pp[N];
map<ull, ull> mmap;
ull cnt[N];
int ne[N];
int slen, tlen;

void getnext()
{
    int j, k;
    j = 0;
    k = -1;
    ne[0] = -1;
    while(j < tlen)
    {
        if(k == -1 || T[j] == T[k])
            ne[++j] = ++k;
        else
            k = ne[k];
    }
}

bool kmp(char *s,char *p)
{
    int m=strlen(s);
    int n=strlen(p);
    for(int i=0,j=-1; i<=m; i++)
    {
        while(j && s[i]!=p[j+1])
        {
            j=ne[j];
        }
        if(s[i]==p[j+1])
        {
            j++;
        }
        if(j==n) //匹配成功
        {
            return true;
        }
    }
    return false;
}

int main(int argc, char const *argv[])
{
    ios;
    int n;
    scanf("%d", &n);
    pp[0] = 1;
    for(int i = 1; i < N; i++)
    {
        pp[i] = 1ll * pp[i - 1] * p % mod;
    }
    for(int i = 1; i <= n; i++)
    {
        cin >> s[i];
        int len = s[i].size();
        ull base = 1;
        ull hs = 0;
        for(int j = len - 1; j >= 0; --j)
        {
            hs += base * s[i][j];
            mmap[hs]++;
            base *= p;
        }
    }

    ull ans = 0;
    for(int i = 1; i <= n; i++)
    {
        T = s[i];
        tlen = T.size();
        ull hs = 0;
        for(int j = 0; j < tlen; j++)
        {
            cnt[j] = 0;
            hs = hs * p + s[i][j];
            if(!mmap.count(hs))
                continue;
            cnt[j] += mmap[hs];
        }
        getnext();
        for(int j = 1; j <= tlen; j++)
        {
            if(ne[j] == 0)
                continue;
            cnt[ne[j] - 1] -= cnt[j - 1];
        }
        for(int j = 0; j < tlen; j++)
        {
            ans = (ans + 1ll * (j + 1) * (j + 1) % mod * cnt[j] % mod) % mod;
        }
    }

    cout << ans << endl;
    return 0;
}

  

B Boundary
C Cover the Tree
D Duration
E Exclusive OR
F Fake Maxpooling
G Greater and Greater
H Happy Triangle
I Interval
J Just Shuffle
K Keyboard Free

 

 

 

൘㘳㲁৫䟽ˈ∄ྲєњ “aba”ˈަѝՊᴹєњࡽ㔰 “a”, “aba” 㻛㇇ࡠˈնᇎ䱵кਚᓄ䈕
“aba” 㘼нᱟ “a”DŽ
原文地址:https://www.cnblogs.com/jxust-Biao/p/13340810.html