[CF1902E] Collapsing Strings

发布时间 2023-12-31 21:32:48作者: 徐子洋

题目链接

考虑拆贡献。

显然答案可以拆成对于所有 \(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;
}