CF1902E

考虑拆贡献。

显然答案可以拆成对于所有 $s_i$ 的每一个后缀的反串,作为前缀在所有串中的出现次数的加和。

这个东西字典树维护一下就行了。

不知道是谁考场上写哈希赛后被人对着模数卡掉了

#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); ++i)
#define FR(i, a, b) for(int i = (a); i >= (b); --i)
using namespace std;
constexpr int N = 1e6 + 10;
int n, tot, cnt[N], t[N][26];
long long ans; string s[N];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n;
    FL(i, 1, n) cin >> s[i], ans += 2ll * n * s[i].size();
    FL(i, 1, n){
        int p = 0, l = s[i].size();
        FR(j, l - 1, 0){
            if(!t[p][s[i][j] - 'a']) t[p][s[i][j] - 'a'] = ++tot;
            ++cnt[p = t[p][s[i][j] - 'a']];
        }
    }
    FL(i, 1, n){
        int p = 0, l = s[i].size();
        FL(j, 0, l - 1){
            if(!t[p][s[i][j] - 'a']) break;
            ans -= cnt[p = t[p][s[i][j] - 'a']] * 2;
        }
    }
    cout << ans << endl;
    return 0;
}
posted @ 2023-12-10 08:35  徐子洋  阅读(7)  评论(0)    收藏  举报  来源