ABC353E 题解
题意
给出
思路
暴力地两两计算显然会超时,需要优化。
考虑按位求解。按照当前位之前的位全部一致的要求分组。因此在每一组中,若当前位某一字母有
为了接着处理后面的位,要在处理时把还没处理完的字符串按照这一位的值分组,处理完这一位后再分组处理下一位。
如此,若设字符串总长度为
具体看代码实现。
代码
#include<iostream>
#include<vector>
#define int long long
using namespace std;
const int N=3e5+10;
int n,ans;
string s[N];
vector <int> st;//初始的组,包含所有字符串
void sol(vector <int> &sg,int pos)
{
vector <int> ts[27];
int c[27];
for(int i=0;i<26;i++) c[i]=0;
for(int k:sg)
{
int id=s[k][pos]-'a';
c[id]++;
if(s[k].size()>pos+1) ts[id].push_back(k);//只有这一位相同,才可能继续在同一组
}//处理这一组中的所有字符串
for(int i=0;i<26;i++) if(c[i]>1)
{
ans+=c[i]*(c[i]-1)/2;//处理贡献
if(ts[i].size()>1) sol(ts[i],pos+1);//继续处理下一位
}
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>s[i],st.push_back(i);
sol(st,0);
cout<<ans;
return 0;
}