競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 314D

ABC314D

原因不明の WA. 小文字(または大文字)に直す自作の関数でWA. 手元では,テストケースが正しく動いていた. 提出したら,テストケースもWA.

対策
std::toupper, std::tolower を用いたら AC.

クエリ先読み
大文字,小文字の入れ替えを毎回実行したら, 最悪ケースで \( O(NQ) \). たとえば,クエリの全てが type 2 のとき.
そこで,大文字,小文字の入れ替えを少なくしたい. 実際には,入れ替えで重要なのは最後の 1回だけである. よって,最後に入れ替えが起きた時刻を覚えておく. ここで,クエリの index を時刻とみなした.
大文字,小文字の入れ替えが高々 1回しか発生しないので, \( O(N+Q) \) で可能. 愚直にシュミレーションして間に合う計算量に落とせたので, その通りに実装すればよい. 下手に工夫をしたりしない方が安全.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

// WA >>>>
char low(char c){
  if('A' <= c && c <= 'Z') return c + ('a'-'A');
}
char up(char c){
  if('a' <= c && c <= 'z') return c - ('a'-'A');
}
// <<<<<<<<<


//---------------------------------------------------------------------------------------------------
int main() {
  ll n,m;
  cin >> n;
  string s; cin >> s;
  ll q; cin >> q;

  vector<tuple<ll,ll,char>> vq(q);
  ll last = -1;
  rep(qi,q){
    ll t,x;
    char c; cin >> t >> x >> c;

    vq[qi] = {t,x,c};
    if(t >= 2) last = qi;
  }

  rep(qi,q){
    auto [t,x,c] = vq[qi];
    if(t == 1){
      x--;
      s[x] = c;
    }else if(t == 2){
      if(qi == last) rep(i,n) s[i] = tolower(s[i]);
    }else{
      if(qi == last) rep(i,n) s[i] = toupper(s[i]);
    }
  }
  cout << s << endl;


  return 0;
}