Submission #607648

#TimeUsernameProblemLanguageResultExecution timeMemory
607648jairRSMutating DNA (IOI21_dna)C++17
100 / 100
272 ms66812 KiB
#include "dna.h"
#include <bits/stdc++.h>
using namespace std;
using vi = vector<int>;

string ga, gb;
map<char, vi> prefixCharA, prefixCharB;
// prefix array of the positions where [c1][c2] c2 is in b instead of c1
map<char, map<char, int>> inPlaceOf[(int)1e5 + 1];

char characters[3] = {'A', 'T', 'C'};

void init(string a, string b)
{
    int n = a.size();
    ga = ' ' + a;
    gb = ' ' + b;

    for (char c : characters)
    {
        prefixCharA[c] = prefixCharB[c] = vi(n + 1, 0);
        for (int i = 1; i <= n; i++)
        {
            prefixCharA[c][i] = (ga[i] == c) + prefixCharA[c][i - 1];
            prefixCharB[c][i] = (gb[i] == c) + prefixCharB[c][i - 1];
        }
    }

    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j < 3; j++)
            for (int k = 0; k < 3; k++)
            {
                if (k == j)
                    continue;
                inPlaceOf[i][characters[j]][characters[k]] =
                    inPlaceOf[i - 1][characters[j]][characters[k]];
            }

        if (ga[i] != gb[i])
            inPlaceOf[i][ga[i]][gb[i]]++;
    }
}

int get_distance(int x, int y)
{
    x++, y++;

    bool pos = true;
    for (char c : characters)
    {
        int countInA = prefixCharA[c][y] - prefixCharA[c][x - 1];
        int countInB = prefixCharB[c][y] - prefixCharB[c][x - 1];
        pos &= (countInA == countInB);
    }

    if (!pos)
        return -1;

    map<char, map<char, int>> countIPO;
    for (int j = 0; j < 3; j++)
        for (int k = j + 1; k < 3; k++)
        {
            char c1 = characters[j], c2 = characters[k];
            countIPO[c1][c2] = inPlaceOf[y][c1][c2] - inPlaceOf[x - 1][c1][c2];
            countIPO[c2][c1] = inPlaceOf[y][c2][c1] - inPlaceOf[x - 1][c2][c1];
        }

    int moves = 0, leftover = 0;

    for (int j = 0; j < 3; j++)
        for (int k = j + 1; k < 3; k++)
        {
            char c1 = characters[j], c2 = characters[k];
            int dif = min(countIPO[c1][c2], countIPO[c2][c1]);
            countIPO[c1][c2] -= dif;
            countIPO[c2][c1] -= dif;
            moves += dif;

            leftover += countIPO[c1][c2];
            leftover += countIPO[c2][c1];
        }

    moves += 2 * leftover / 3;

    return moves;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...