题解/算法 {E - Yet Another Sigma Problem(最长公共前缀)}

题解/算法 {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" (即abcdS[i]的前缀), 那么对于满足(S[i], S[j]) == abcj 也就是要么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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值