# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1142084 | vyaduct | Mutating DNA (IOI21_dna) | C++20 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
#include "dna.h"
#define sz(a) (int)(a).size()
using namespace std;
const int N = 100'001;
int cntA[N][3], cntB[N][3];
int pref1[N], pref2[N], pref3[N];
string A, B;
int sum(int ch, int x, int y, bool A){
if (A) return cntA[y][ch]-(x == 0 ? 0 : cntA[x-1][ch]);
else return cntB[y][ch]-(x == 0 ? 0 : cntB[x-1][ch]);
}
int ord(char c){
// index by char
if (c == 'A') return 0;
else if (c == 'T') return 1;
else return 2;
}
bool check(int x, int y){
for (int i=0;i<3;i++){
int sumA = sum(i, x, y, true);
int sumB = sum(i, x, y, false);
if (sumA != sumB){
return false;
}
}
return true;
}
void init(string a, string b) {
A = a, B = b;
memset(cntA, 0, sizeof(cntA));
memset(cntB, 0, sizeof(cntB));
// prefsum precomputation
int n = sz(a);
for (int i=0;i<n;i++){
// string a
cntA[i][0] = (i == 0 ? 0 : cntA[i-1][0]) + (ord(a[i]) == 0);
cntA[i][1] = (i == 0 ? 0 : cntA[i-1][1]) + (ord(a[i]) == 1);
cntA[i][2] = (i == 0 ? 0 : cntA[i-1][2]) + (ord(a[i]) == 2);
// string b
cntB[i][0] = (i == 0 ? 0 : cntB[i-1][0]) + (ord(b[i]) == 0);
cntB[i][1] = (i == 0 ? 0 : cntB[i-1][1]) + (ord(b[i]) == 1);
cntB[i][2] = (i == 0 ? 0 : cntB[i-1][2]) + (ord(b[i]) == 2);
}
for (int i=0;i<n;i++){
pref1[i] = (i == 0 ? 0 : pref1[i-1]) + (A[i] == 'T' && B[i] != 'T');
pref2[i] = (i == 0 ? 0 : pref2[i-1]) + (A[i] == 'A' && B[i] != 'A');
pref3[i] = (i == 0 ? 0 : pref3[i-1]) + (A[i] == 'C' && B[i] != 'C');
}
}
// Accepted first subtask, (y-x <= 2)
int subtask1(int x, int y){
int size = y-x+1;
if (size == 1) return 0;
if (size == 2){
return A[x] == B[x] ? 0 : 1;
} else {
int diff=0;
for (int i=x;i<=y;i++){
diff += (A[i] == B[i] ? 0 : 1);
}
if (diff != 0) return diff-1;
else return diff;
}
}
int subtask2_3(int x, int y){
int res1 = pref1[y]-(x==0 ? 0 : pref1[x-1]);
int res2 = pref2[y]-(x==0 ? 0 : pref2[x-1]);
int res3 = pref3[y]-(x==0 ? 0 : pref3[x-1]);
return min(res1, res2, res3);
}
int get_distance(int x, int y) {
bool possible = check(x,y);
if (!possible){
return -1;
}
if (y-x <= 2) return subtask1(x,y);
else return subtask2_3(x,y);
}