1. 程式人生 > 實用技巧 >【Luogu P4127】[AHOI2009]同類分佈

【Luogu P4127】[AHOI2009]同類分佈

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Ž