2020牛客暑期多校训练营(第二场)A All with Pairs

All with Pairs

https://ac.nowcoder.com/acm/contest/5667/A

这题难点应该就是去重难想些吧

首先把每个字符串的后缀都hash了存到map里,然后从每个字符串遍历,从前到后,第i个字符串的第j个点字符,我们得到前缀的hash值是x,ans[i][j]=mp[x],然后ans[i][next[j]]-ans[i][j],这就是在去重,next就是kmp的next数组,最后答案是

 具体描述下这个去重吧,应该会好理解点

就比如现在只有一个字符串ababa

从后往前存后缀
mp[a]=1;
mp[ba]=1;
mp[aba]=1;
mp[baba]=1;
mp[ababa]=1;

然后遍历前缀
ans[1]=mp[a]=1;
ans[2]=mp[ab]=0;
ans[3]=mp[aba]=1;
ans[4]=mp[abab]=0;
ans[5]=mp[ababa]=1;

然后从前往后
ans[next]-=ans[i]
最后就只有ans[5]=1了

为什么是ans[next]-=ans[i]呢?因为next已经存在于当前字符串里了,所以next要减去ans[i]
#include<stdio.h>
#include<map>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
typedef unsigned long long ull;
#define maxn 1050000
#define mod 998244353
ull base=131;
string a[maxn];
ull p[maxn];
map<ull,ull>mp;
ull ans[maxn];
ull kmp[maxn];
ull ans1[maxn];
void js(string b)
{
    ull j=0,lb=b.size()-1;
    for(int i=2;i<=lb;i++)
    {
        while(j&&b[i]!=b[j+1])
        {
            j=kmp[j];
        }
        if(b[i]==b[j+1]) j++;
        kmp[i]=j;
    }
    //for(ull i=1;i<=lb;i++) cout<<"kmp["<<i<<"]="<<kmp[i]<<'\n';
}
int main()
{
    ull n;
    cin>>n;
    p[0]=1;
    for(ull i=1;i<=maxn-10;i++)
    {
        p[i]=(p[i-1]*base);
    }
    for(ull i=1;i<=n;i++)
    {
        cin>>a[i];
        a[i]=' '+a[i];
        ull len=a[i].size()-1;
        ull s=0;
        for(ull j=len;j>=1;j--)
        {
            s=p[len-j]*a[i][j]+s;
            mp[s]++;
            //cout<<"mp["<<s<<"]="<<mp[s]<<'\n';
        }
 
    }
    for(ull i=1;i<=n;i++)
    {
        ull len=a[i].size()-1;
        ull x=0,y=0;
        //cout<<"i="<<i<<'\n';
        js(a[i]);
 
        for(ull j=1;j<=len;j++)
        {
            x=x*base+a[i][j];
            y=p[j-1]*a[i][len-j+1]+y;
            //ans[j]+=mp[x];
            ans1[j]=mp[x];
            ans1[kmp[j]]-=ans1[j];
 
            //cout<<"mp["<<x<<"]="<<mp[x]<<'\n';
            //ans[j]-=(x==y);
        }
        for(ull j=1;j<=len;j++) ans[j]+=ans1[j];
    }
    ll w=0;
    for(ull i=1;i<=maxn-10;i++)
    {
        w+=i*i*ans[i];
        w%=mod;
        //cout<<"ans["<<i<<"]="<<ans[i]<<'\n';
    }
    cout<<w<<'\n';
}


全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务