#include <cstdio>
#include <set>
#include <map>
#define DEBUG false
using namespace std;
struct triphash{
long long hash_18102121071511;
long long hash_24722820632683;
long long hash_61246398225527;
auto operator<=>(const triphash &other) const = default;
};
long long newhash(long long hash_mod, long long oldhash, char newletter) {
int letter_val = newletter - 96;
return (oldhash * 7LL + letter_val) % hash_mod;
}
triphash new_triphash(triphash old_triphash, char newletter) {
triphash nw{};
nw.hash_18102121071511 = newhash(18102121071511LL, old_triphash.hash_18102121071511, newletter);
nw.hash_24722820632683 = newhash(24722820632683LL, old_triphash.hash_24722820632683, newletter);
nw.hash_61246398225527 = newhash(61246398225527LL, old_triphash.hash_61246398225527, newletter);
return nw;
}
char word[50001];
void rebuild_map(int n) {
// builds map based on the `word` array;
// outputs result
map<triphash, long long> counts;
triphash empty_seq{};
counts[empty_seq] = 1;
for (int i = 0; i < n; ++ i) {
char next_letter = word[i];
if constexpr(DEBUG) printf("Adding letter %c\n", next_letter);
map<triphash, long long> oldcounts = counts;
for (auto [x, y]: oldcounts) {
if constexpr(DEBUG) printf(" to hash %lld (%lld) -> %lld\n", x.hash_18102121071511, y, new_triphash(x, next_letter).hash_18102121071511);
counts[new_triphash(x, next_letter)] += y;
}
}
long long twos = 0;
for (auto [x, y]: counts) {
if constexpr(DEBUG) printf("Hash %lld: val %lld\n", x.hash_18102121071511, y);
if (y > 1) twos++;
}
printf("%lld\n", twos);
}
int main() {
int n, q;
scanf("%d %d\n", &n, &q);
for (int i = 0; i < n; ++i) {
scanf("%c", &word[i]);
}
rebuild_map(n);
for (int qi = 0; qi < q; ++qi) {
int a;
char c;
scanf("%d %c", &a, &c);
word[a-1] = c;
rebuild_map(n);
}
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include <cstdio> #include <set> #include <map> #define DEBUG false using namespace std; struct triphash{ long long hash_18102121071511; long long hash_24722820632683; long long hash_61246398225527; auto operator<=>(const triphash &other) const = default; }; long long newhash(long long hash_mod, long long oldhash, char newletter) { int letter_val = newletter - 96; return (oldhash * 7LL + letter_val) % hash_mod; } triphash new_triphash(triphash old_triphash, char newletter) { triphash nw{}; nw.hash_18102121071511 = newhash(18102121071511LL, old_triphash.hash_18102121071511, newletter); nw.hash_24722820632683 = newhash(24722820632683LL, old_triphash.hash_24722820632683, newletter); nw.hash_61246398225527 = newhash(61246398225527LL, old_triphash.hash_61246398225527, newletter); return nw; } char word[50001]; void rebuild_map(int n) { // builds map based on the `word` array; // outputs result map<triphash, long long> counts; triphash empty_seq{}; counts[empty_seq] = 1; for (int i = 0; i < n; ++ i) { char next_letter = word[i]; if constexpr(DEBUG) printf("Adding letter %c\n", next_letter); map<triphash, long long> oldcounts = counts; for (auto [x, y]: oldcounts) { if constexpr(DEBUG) printf(" to hash %lld (%lld) -> %lld\n", x.hash_18102121071511, y, new_triphash(x, next_letter).hash_18102121071511); counts[new_triphash(x, next_letter)] += y; } } long long twos = 0; for (auto [x, y]: counts) { if constexpr(DEBUG) printf("Hash %lld: val %lld\n", x.hash_18102121071511, y); if (y > 1) twos++; } printf("%lld\n", twos); } int main() { int n, q; scanf("%d %d\n", &n, &q); for (int i = 0; i < n; ++i) { scanf("%c", &word[i]); } rebuild_map(n); for (int qi = 0; qi < q; ++qi) { int a; char c; scanf("%d %c", &a, &c); word[a-1] = c; rebuild_map(n); } return 0; } |
English