ABC 287 E - Karuta(字典树模板题)

https://atcoder.jp/contests/abc287/tasks/abc287_e

E - Karuta

题目大意:

给定n个字符串数组Si,问每个字符串与其他字符串的最长公共前缀是多少。
Sample Input 2  
11
abracadabra
bracadabra
racadabra
acadabra
cadabra
adabra
dabra
abra
bra
ra
a
Sample Output 2  
4
3
2
1
0
1
0
4
3
2
1

典型的字典树模板题
(学了个佬儿用的模板哈哈哈,舒适)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18,MINN=-1e18;
const LL N=1e6+10,M=4010;
const LL mod=998244353;
const double PI=3.1415926535;
#define endl '\n'
struct Trie
{
    LL nex[N][26],cnt,vis[N];
    void insert(string &s)//插入字符串
    {
        LL p=0,l=s.size();
        vis[p]++;
        for(int i=0;i<l;i++)
        {
            int c=s[i]-'a';
            if(!nex[p][c]) nex[p][c]=++cnt;//如果没有就添加节点
            p=nex[p][c];
            vis[p]++;
        }
    }
    int find(string &s)
    {
        int p=0,l=s.size(),res=0;
        for(int i=0;i<l;i++)
        {
            int c=s[i]-'a';
            p=nex[p][c];
            if(vis[p]>1) res=max(res,i+1);
        }
        return res;
    }
};
Trie trie;
string s[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    //cin>>T;
    while(T--)
    {
        LL n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>s[i];
            trie.insert(s[i]);
        }
        for(int i=1;i<=n;i++)
        {
            cout<<trie.find(s[i])<<endl;
        }
    }
    return 0;
}
posted @ 2023-03-01 21:38  Vijurria  阅读(28)  评论(0编辑  收藏  举报