20240418
This commit is contained in:
84
ACMOJ-2121.cpp
Normal file
84
ACMOJ-2121.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
typedef long double LDB;
|
||||
const int kMaxN = (1 << 20) + 10;
|
||||
int T;
|
||||
char s[kMaxN];
|
||||
int z[kMaxN];
|
||||
int suf_cnt[26], pre_cnt[26];
|
||||
int tot_bucket[kMaxN];
|
||||
inline void Flip(char ch, int *cnt, int &occur) {
|
||||
cnt[ch - 'a'] ^= 1;
|
||||
if (cnt[ch - 'a'])
|
||||
occur++;
|
||||
else
|
||||
occur--;
|
||||
}
|
||||
LL solve() {
|
||||
int n = strlen(s);
|
||||
memset(z, 0, sizeof(z));
|
||||
for (int i = 1, l = 0, r = 0; i < n; ++i) {
|
||||
if (i <= r && z[i - l] < r - i + 1) {
|
||||
z[i] = z[i - l];
|
||||
} else {
|
||||
z[i] = max(0, r - i + 1);
|
||||
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
|
||||
}
|
||||
if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
|
||||
}
|
||||
LL res = 0;
|
||||
int even_A_tot = 0;
|
||||
int odd_A_tot = 0;
|
||||
memset(suf_cnt, 0, sizeof(suf_cnt));
|
||||
for (int i = 0; i < n; i++) suf_cnt[s[i] - 'a'] ^= 1;
|
||||
int all_occur_tot = 0, suf_occur_tot = 0, pre_occur_tot = 0;
|
||||
for (int i = 0; i < 26; i++) all_occur_tot += suf_cnt[i];
|
||||
memset(pre_cnt, 0, sizeof(pre_cnt));
|
||||
suf_occur_tot = all_occur_tot;
|
||||
Flip(s[0], suf_cnt, suf_occur_tot);
|
||||
memset(tot_bucket, 0, sizeof(tot_bucket));
|
||||
for (int i = 1; i <= n - 1; i++) {
|
||||
int odd_C_tot = ceil((min(z[i], n - i - 1) / i + 1) / 2.0);
|
||||
int even_C_tot = ((min(z[i], n - i - 1) / i + 1) / 2.0);
|
||||
res += odd_A_tot * (LL)odd_C_tot;
|
||||
res += even_A_tot * (LL)even_C_tot;
|
||||
// printf("A(%d,%d)\n", odd_A_tot, odd_C_tot);
|
||||
// printf("B(%d,%d)\n", even_A_tot, even_C_tot);
|
||||
if (i == n - 1) break;
|
||||
int old_suf_occur_tot = suf_occur_tot;
|
||||
Flip(s[i], suf_cnt, suf_occur_tot);
|
||||
// Flip(s[i - 1], pre_cnt, pre_occur_tot, tot_bucket);
|
||||
pre_cnt[s[i - 1] - 'a'] ^= 1;
|
||||
if (pre_cnt[s[i - 1] - 'a']) {
|
||||
pre_occur_tot++;
|
||||
} else {
|
||||
pre_occur_tot--;
|
||||
}
|
||||
tot_bucket[pre_occur_tot]++;
|
||||
if (pre_occur_tot <= old_suf_occur_tot) odd_A_tot++;
|
||||
if (old_suf_occur_tot < suf_occur_tot)
|
||||
odd_A_tot += tot_bucket[suf_occur_tot];
|
||||
else
|
||||
odd_A_tot -= tot_bucket[old_suf_occur_tot];
|
||||
// printf("i=%d all_occur_tot=%d pre_occur_tot=%d suf_occur_tot=%d\n", i,
|
||||
// all_occur_tot, pre_occur_tot, suf_occur_tot);
|
||||
// odd_A_tot += (pre_occur_tot <= suf_occur_tot ? 1 : 0);
|
||||
even_A_tot += (pre_occur_tot <= all_occur_tot ? 1 : 0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int main() {
|
||||
#ifdef local
|
||||
freopen("pro.in", "r", stdin);
|
||||
#endif
|
||||
scanf("%d", &T);
|
||||
while (T-- > 0) {
|
||||
scanf("%s", s);
|
||||
printf("%lld\n", solve());
|
||||
}
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user