Official

C - Error Correction Editorial by en_translator


Consider how to determine if \(S_i\) can be equal to \(T\), i.e. with \(T \coloneqq S_i\), one of the four conditions in the problem statement may hold. The original problem can be solved by judging this for each \(I\).

Let \(T \coloneqq S_i\). Inspect \(T\) and \(T'\) from the beginning to count how many initial characters of them coincide; let \(A\) be the maximum length of coinciding prefix. Also, let \(B\) be the maximum length of coinciding suffix. For example, if we have abcd and abcdacd, the first three characters abc coincide, and so do the last two characters cd.

Then, the four conditions can be rephrased as follows, where \(|T|\) and \(|T'|\) denotes the lengths of \(T\) and \(T'\), respectively:

  • \(T'\) equals \(T\): \(A = B = |T| = |T'|\)
  • \(T'\) is obtained by inserting a lowercase English letter to a position of \(T\) (possibly at the beginning or at the end): \(A+B \geq |T| = |T'|-1\)
  • \(T'\) is obtained by removing one character from \(T\): \(A+ B \geq |T|-1 = |T'|\)
  • \(T\) is obtained by replacing one character of \(T\) with another lowercase English letter: \(A +B = |T| -1 = |T'| - 1\)

Therefore, it is sufficient to actually check if \(A, B, |T|\), and \(|T'|\) satisfy one of the four conditions above.

The following is sample code in C++ language.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;

ll n;
string s[500001], t2;
ll a[500001], b[500001];

ll calc(const string &s, const string &t)
{
  for(int i = 0; i < (int)t.size(); i++){
    if(i >= s.size()) return s.size();
    if(s[i] != t[i]) return i;
  }
  return t.size();
}

int main(void){
  cin >> n >> t2;
  for(int i = 1; i <= n; i++) cin >> s[i];

  for(int i = 1; i <= n; i++) a[i] = calc(s[i], t2);
  reverse(t2.begin(), t2.end());
  for(int i = 1; i <= n; i++){
    reverse(s[i].begin(), s[i].end());
    b[i] = calc(s[i], t2);
  }
  
  vector<ll> ans;
  for(int i = 1; i <= n; i++){
    const string &t = s[i];
    bool flag = false;
    if(a[i] == t.size() && t.size() == t2.size()) flag = true;
    if(a[i]+b[i] >= t.size() && t.size()+1 == t2.size()) flag = true;
    if(a[i]+b[i] >= t.size()-1 && t.size()-1 == t2.size()) flag = true;
    if(a[i]+b[i] == t.size()-1 && t.size() == t2.size()) flag = true;
    if(flag) ans.push_back(i);
  }
  
  cout << ans.size() << endl;
  for(auto x : ans) cout << x << " ";
  cout << endl;
  
  return 0;
}

posted:
last update: