采用了直接模拟时计算答案。
#include<iostream>
#include<algorithm>
#include<vector>
typedef std::string Str;
using namespace std;
const int _=1e6*2;
class trie{
private:
int son[2][_],size =1,fa[_] = {0,1,0},f[_] ,end[_];
int get(int o){
if(son[0][o] && son[1][o])
return min(f[son[0][o]],f[son[1][o]])+1;
else
return 1;
}
void create(int fax,int lr){
f[son[lr][fax] = ++size] = 1,
fa[son[lr][fax]] = fax;
}
void go(int&o,int lr){
if(son[lr][o] == 0) create(o,lr);
o = son[lr][o];
}
public:
void upd(int o){
if(f[o] != get(o))
f[o] = get(o), upd(fa[o]);
}
int add(string s){
int cur = 1;
for(char sx: s)
go(cur,sx =='1');
++ end[cur];
return cur;
}
int modif(int o){
if( o == 0) return 0;
//cout<<"modif!"<<o<<endl;
int ans = 0;
//ans += modif(son[0][o])+modif(son[1][o]);
if(son[0][o]==0 && son[1][o]==0){
if(end[o]>1)
create(o,0), -- end[o], ++ end[son[0][o]],
ans += modif(o) +1 ;//,cout<<"a\n";
}
else if(end[o]>0){
int toson = -1; -- end[o];
for(int ab :{0,1}){
if(son[ab][o]==0){
create(o,ab),
toson = ab;
break;
}
}
if(toson == -1)
toson = f[son[0][o]] <= f[son[1][o]] ? 0:1;
++end[son[toson][o]], ans += modif(son[toson][o]) +modif(o) +1;
//cout<<"b\n";
//f[o] = get(o);
}
f[o]= get(o);
return ans;
}
}treex;
int n, cnt = 0;
vector<Str> ids;
vector<int> nods;
int main(){
ios::sync_with_stdio(0),
cin.tie(0),cout.tie(0);
cin>>n,ids.resize(n);
for(Str&ix:ids)
cin>>ix;
sort(ids.begin(),ids.end(),
[&](Str s1,Str s2)
{return s1.length()>s2.length();});
for(int i=0; i<n ; i++)
nods.push_back(treex.add(ids[i]));
for(int nod: nods)
cnt += treex.modif(nod), treex.upd(nod);
cout<<cnt<<endl;
}