H - Duplicate 解説 by en_translator
First of all, if \(S\) has adjacent 2
-or-greater digits, then the answer is -1
.
We consider the other cases. For example, let \(S=\) 1121131
. S
transitions by the operations as follows:
1121131
111211113
11112111111
11111211111
111111211111
\(\vdots\)
We can observe the following property from the sequences:
- The suffix consisting of the same digits (like
3
and111111
above) is shortened one by one, and eventually vanishes. - The occurrences of digits between
2
and9
that is not in such a suffix do not decrease. - Consecutive occurrences of
1
s that is not in such a suffix increases by \((x-1)\) in each step, where \(x\) is the preceding digit. For example, the occurrences of leading11
increases by \(2-1=1\) in each step.
The point of this rule is that consecutive occurrences of the same digits decrease its length only when it is a suffix. Thus, the answer can be found by storing \(S\) in run-length encoding, and simulating the lengths of \(S\) and the number of operations while popping the tail of run-length-compressed sequence. (For more details, please refer to the sample code.)
The complexity is \(\mathrm{O}(N)\), which is fast enough.
- Sample code (C++)
#include <bits/stdc++.h>
using namespace std;
#include "atcoder/modint.hpp"
using mint = atcoder::modint998244353;
vector<pair<char, int>> RunLengthEncoding(string& S) {
if (S.empty()) return {};
vector<pair<char, int>> ret;
char c = S[0];
int n = 1;
for (int i = 1; i < (int)S.size(); i++) {
if (S[i] == c)
n++;
else {
ret.emplace_back(c, n);
c = S[i], n = 1;
}
}
ret.emplace_back(c, n);
return ret;
}
int main() {
int N;
string S;
cin >> N >> S;
for (int i = 0; i + 1 < N; i++) {
if (S[i] >= '2' and S[i + 1] >= '2') {
cout << "-1\n";
exit(0);
}
}
auto rle = RunLengthEncoding(S);
mint t = 0;
char last = '1';
while (!rle.empty()) {
char c;
mint n;
tie(c, n) = rle.back();
rle.pop_back();
if (c == '1') {
n += t * (last - '1');
t += n;
} else {
t += 1;
}
last = c;
}
cout << (t - 1).val() << "\n";
}
投稿日時:
最終更新: