题解:CF1270F Awesome Substrings
link
思路
考虑根号分治,令
设当前段
若
若
总时间复杂度为
代码
// BLuemoon_
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int kMaxN = 2e5 + 5, kMaxB = 455;
LL n, B, s[kMaxN], x, ans;
int cnt[kMaxN * kMaxB];
string t;
int main() {
cin >> t, n = t.size(), t = ' ' + t, B = sqrt(n);
for (int i = 1; i <= n; i++) {
s[i] = s[i - 1] + t[i] - '0';
}
for (LL j = 1; j <= B; j++) {
for (int i = 0; i <= n; i++) {
x = j * s[i] - i + n, cnt[x]++;
}
for (int i = 0; i <= n; i++) {
x = j * s[i] - i + n, ans += 1ll * (cnt[x] - 1) * cnt[x] / 2, cnt[x] = 0;
}
}
for (LL j = 1; j <= B; j++) {
for (LL i = 0, L = 1, R = -1; i <= n; i++) {
for (; L <= n && s[L] - s[i] < j; L++) {
}
if (L == n + 1) {
break;
}
!~R && (R = L);
for (; R < n && s[R + 1] - s[i] <= j; R++) {
}
LL l = max(L - i, B * j + 1), r = R - i;
l <= r && (ans += r / j - (l - 1) / j);
}
}
cout << ans << '\n';
return 0;
}