#include <bits/stdc++.h>
using namespace std;
#ifdef DEBUG
auto &operator<<(auto &o, pair<auto, auto> p) {
return o << "(" << p.first << ", " << p.second <<")";
}
auto operator<<(auto &o, auto x)-> decltype(x.end(), o) {
o << "{";int i = 0;
for(auto e : x) o << ", "+!i++<<e;
return o <<"}";
}
#define debug(x...) cerr << "["#x"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(x)
#else
#define debug(...) {}
#endif
#define int long long
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define pb push_back
#define fi first
#define se second
typedef pair <int, int> pii;
int const mod = 1e9+123;
int const MOD = 998244353;
int solve2(string &s) {
map <int, int> M;
int const n = sz(s);
for (int i=1; i<(1<<n); ++i) {
int hsh = 0, p = 1;
for (int j=0; j<n; ++j) {
if ((1<<j) & i) {
hsh = (hsh + (p*(s[j] - '0' + 1))%mod);
p = (p*7ll)%mod;
}
}
M[hsh]++;
}
int ret = 0;
for (auto &[x, y] : M) {
if (y > 1) ret++;
}
return ret%MOD;
}
int solve(string &s) {
debug("SOLVE-------", s);
int const n = sz(s);
vector <vector <int> > ile(n+1, vector <int>(7));
vector <int> last(7, 0);
vector <int> ilen(n+1);
ilen[0] = 1;
for (int i=1; i<=n; ++i) {
int lt = s[i-1] - 'a';
ilen[i] = (MOD + (2ll * ilen[i-1]) - (last[lt] > 0 ? ilen[last[lt]-1] : 0))%MOD;
last[lt] = i;
}
debug(ilen);
last = vector <int> (7, 0);
for (int i=1; i<=n; ++i) {
int c = s[i-1] - 'a';
// pelny prefix wystepuje raz na pewno
// kazde slowo, ktore wystapilo raz do tamtej literki mozna przedluzyc
for (int j=0; j<6; ++j){
if (j == c) { // ta sama literka
ile[i][c] = (ile[i][c] + ile[i-1][c])%MOD;
}
else {
ile[i][j] = ile[i-1][j];
if (last[j] >= last[c])
ile[i][c] = (ile[i][c] + ile[i-1][j])%MOD;
}
}
if (last[c] == 0) ile[i][c] = (ile[i][c]+1)%MOD;
last[c] = i;
}
debug(sz(ile), n);
for (int i=1; i<=n; ++i) {
debug(i, "------------");
debug(ile[i]);
}
int ret = 0;
for (int i=0; i<6; ++i) {
ret = (ret + ile[n][i])%MOD;
}
return ((2ll * MOD) - 1ll + ilen[n] - ret)%MOD;
}
void test() {
debug("TC______________________");
int n, q; cin>>n>>q;
string s; cin>>s;
cout<<solve(s)<<'\n';
debug("asdasd");
for (int i=0; i<q; ++i) {
int p; char c;
cin>>p>>c;
s[p-1] = c;
cout<<solve(s)<<'\n';
}
}
signed main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int t = 1;
while (t--) {
test();
}
}
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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | #include <bits/stdc++.h> using namespace std; #ifdef DEBUG auto &operator<<(auto &o, pair<auto, auto> p) { return o << "(" << p.first << ", " << p.second <<")"; } auto operator<<(auto &o, auto x)-> decltype(x.end(), o) { o << "{";int i = 0; for(auto e : x) o << ", "+!i++<<e; return o <<"}"; } #define debug(x...) cerr << "["#x"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(x) #else #define debug(...) {} #endif #define int long long #define all(x) x.begin(), x.end() #define sz(x) (int)(x).size() #define pb push_back #define fi first #define se second typedef pair <int, int> pii; int const mod = 1e9+123; int const MOD = 998244353; int solve2(string &s) { map <int, int> M; int const n = sz(s); for (int i=1; i<(1<<n); ++i) { int hsh = 0, p = 1; for (int j=0; j<n; ++j) { if ((1<<j) & i) { hsh = (hsh + (p*(s[j] - '0' + 1))%mod); p = (p*7ll)%mod; } } M[hsh]++; } int ret = 0; for (auto &[x, y] : M) { if (y > 1) ret++; } return ret%MOD; } int solve(string &s) { debug("SOLVE-------", s); int const n = sz(s); vector <vector <int> > ile(n+1, vector <int>(7)); vector <int> last(7, 0); vector <int> ilen(n+1); ilen[0] = 1; for (int i=1; i<=n; ++i) { int lt = s[i-1] - 'a'; ilen[i] = (MOD + (2ll * ilen[i-1]) - (last[lt] > 0 ? ilen[last[lt]-1] : 0))%MOD; last[lt] = i; } debug(ilen); last = vector <int> (7, 0); for (int i=1; i<=n; ++i) { int c = s[i-1] - 'a'; // pelny prefix wystepuje raz na pewno // kazde slowo, ktore wystapilo raz do tamtej literki mozna przedluzyc for (int j=0; j<6; ++j){ if (j == c) { // ta sama literka ile[i][c] = (ile[i][c] + ile[i-1][c])%MOD; } else { ile[i][j] = ile[i-1][j]; if (last[j] >= last[c]) ile[i][c] = (ile[i][c] + ile[i-1][j])%MOD; } } if (last[c] == 0) ile[i][c] = (ile[i][c]+1)%MOD; last[c] = i; } debug(sz(ile), n); for (int i=1; i<=n; ++i) { debug(i, "------------"); debug(ile[i]); } int ret = 0; for (int i=0; i<6; ++i) { ret = (ret + ile[n][i])%MOD; } return ((2ll * MOD) - 1ll + ilen[n] - ret)%MOD; } void test() { debug("TC______________________"); int n, q; cin>>n>>q; string s; cin>>s; cout<<solve(s)<<'\n'; debug("asdasd"); for (int i=0; i<q; ++i) { int p; char c; cin>>p>>c; s[p-1] = c; cout<<solve(s)<<'\n'; } } signed main() { ios_base::sync_with_stdio(0); cin.tie(0); int t = 1; while (t--) { test(); } } |
English