题解/算法 {E - Yet Another Sigma Problem(最长公共前缀)}
@LINK: https://atcoder.jp/contests/abc353/tasks/abc353_e
;
对于当前字符串S[i]
, 我们计算所有形如(S[i], S[<i])
的最长公共前缀长度之和;
即把S[<i]
都放到Trie里, 然后我们执行Tr.Query( S[i])
, 比如当前是curNode
她表示abc
, 然后她的下一个节点是nexNode = "abcd"
(即abcd
是S[i]
的前缀), 那么对于满足(S[i], S[j]) == abc
的j
也就是要么S[j]='abc'
要么S[j] = "abc (!d) ..."
, 此时 你让curNode.PrefixCount - nexNode.PrefixCount
就等于j
的个数;
long long ANS = 0;
{
int branchId = GETbranchID( _str[0]);
if( false == NODEisEXIST( curNode->SonPtr[ branchId])){ return ANS;}
curNode = curNode->SonPtr[ branchId];
}
for( int ind = 0; ind+1 < _len; ++ind){
//>< `curNode = S[...,ind]`;
int branchId = GETbranchID( _str[ind+1]);
auto cont = curNode->PrefixCount;
if( 0 == NODEisEXIST( curNode->SonPtr[ branchId])){
ANS += cont*1LL*(ind+1);
return ANS;
}
ANS += (cont - curNode->SonPtr[branchId]->PrefixCount)*1LL*(ind+1);
curNode = curNode->SonPtr[ branchId];
}
ANS += curNode->PrefixCount*1LL*_len;
return ANS;