Submission #1234762

#TimeUsernameProblemLanguageResultExecution timeMemory
1234762gry3125Mutating DNA (IOI21_dna)C++20
100 / 100
263 ms13776 KiB
#include "dna.h"
#include <bits/stdc++.h>
#define ll long long int

using namespace std;
string a, b; int n;
vector<ll> as[3], bs[3];
// [0] = A, [1] = T, [2] = C



vector<int> at;
void atupd(int v, int tl, int tr, int pos, int val) {
	if (tl == tr) {at[v] = val; return;}
	int tm = (tl + tr) / 2;
	if (pos <= tm) atupd(2*v, tl, tm, pos, val);
	else atupd(2*v+1, tm+1, tr, pos, val);
	at[v] = at[2*v] + at[2*v+1];
}
ll atquery(int v, int tl, int tr, int l, int r) {
	if (l > r) return 0;
	if (l == tl && r == tr) return at[v];
	int tm = (tl + tr) / 2;
	ll lf = atquery(2*v, tl, tm, l, min(tm, r));
	ll rg = atquery(2*v+1, tm+1, tr, max(tm+1, l), r);
	return lf + rg;
}

vector<int> ta;
void taupd(int v, int tl, int tr, int pos, int val) {
	if (tl == tr) {ta[v] = val; return;}
	int tm = (tl + tr) / 2;
	if (pos <= tm) taupd(2*v, tl, tm, pos, val);
	else taupd(2*v+1, tm+1, tr, pos, val);
	ta[v] = ta[2*v] + ta[2*v+1];
}
ll taquery(int v, int tl, int tr, int l, int r) {
	if (l > r) return 0;
	if (l == tl && r == tr) return ta[v];
	int tm = (tl + tr) / 2;
	ll lf = taquery(2*v, tl, tm, l, min(tm, r));
	ll rg = taquery(2*v+1, tm+1, tr, max(tm+1, l), r);
	return lf + rg;
}

vector<int> tc;
void tcupd(int v, int tl, int tr, int pos, int val) {
	if (tl == tr) {tc[v] = val; return;}
	int tm = (tl + tr) / 2;
	if (pos <= tm) tcupd(2*v, tl, tm, pos, val);
	else tcupd(2*v+1, tm+1, tr, pos, val);
	tc[v] = tc[2*v] + tc[2*v+1];
}
ll tcquery(int v, int tl, int tr, int l, int r) {
	if (l > r) return 0;
	if (l == tl && r == tr) return tc[v];
	int tm = (tl + tr) / 2;
	ll lf = tcquery(2*v, tl, tm, l, min(tm, r));
	ll rg = tcquery(2*v+1, tm+1, tr, max(tm+1, l), r);
	return lf + rg;
}

vector<int> ct;
void ctupd(int v, int tl, int tr, int pos, int val) {
	if (tl == tr) {ct[v] = val; return;}
	int tm = (tl + tr) / 2;
	if (pos <= tm) ctupd(2*v, tl, tm, pos, val);
	else ctupd(2*v+1, tm+1, tr, pos, val);
	ct[v] = ct[2*v] + ct[2*v+1];
}
ll ctquery(int v, int tl, int tr, int l, int r) {
	if (l > r) return 0;
	if (l == tl && r == tr) return ct[v];
	int tm = (tl + tr) / 2;
	ll lf = ctquery(2*v, tl, tm, l, min(tm, r));
	ll rg = ctquery(2*v+1, tm+1, tr, max(tm+1, l), r);
	return lf + rg;
}

vector<int> ca;
void caupd(int v, int tl, int tr, int pos, int val) {
	if (tl == tr) {ca[v] = val; return;}
	int tm = (tl + tr) / 2;
	if (pos <= tm) caupd(2*v, tl, tm, pos, val);
	else caupd(2*v+1, tm+1, tr, pos, val);
	ca[v] = ca[2*v] + ca[2*v+1];
}
ll caquery(int v, int tl, int tr, int l, int r) {
	if (l > r) return 0;
	if (l == tl && r == tr) return ca[v];
	int tm = (tl + tr) / 2;
	ll lf = caquery(2*v, tl, tm, l, min(tm, r));
	ll rg = caquery(2*v+1, tm+1, tr, max(tm+1, l), r);
	return lf + rg;
}

vector<int> ac;
void acupd(int v, int tl, int tr, int pos, int val) {
	if (tl == tr) {ac[v] = val; return;}
	int tm = (tl + tr) / 2;
	if (pos <= tm) acupd(2*v, tl, tm, pos, val);
	else acupd(2*v+1, tm+1, tr, pos, val);
	ac[v] = ac[2*v] + ac[2*v+1];
}
ll acquery(int v, int tl, int tr, int l, int r) {
	if (l > r) return 0;
	if (l == tl && r == tr) return ac[v];
	int tm = (tl + tr) / 2;
	ll lf = acquery(2*v, tl, tm, l, min(tm, r));
	ll rg = acquery(2*v+1, tm+1, tr, max(tm+1, l), r);
	return lf + rg;
}



int get_distance(int x, int y) {
	for (int i = 0; i < 3; i++) {
		ll suma = as[i][y], sumb = bs[i][y];
		if (x > 0) {
			suma -= as[i][x-1];
			sumb -= bs[i][x-1];
		}
		if (suma != sumb) return -1;
	}
	int at[2] = { }, tc[2] = { }, ca[2] = { };
	at[0] = atquery(1, 1, (1LL << 17), x+1, y+1);
	at[1] = taquery(1, 1, (1LL << 17), x+1, y+1);
	tc[0] = tcquery(1, 1, (1LL << 17), x+1, y+1);
	tc[1] = ctquery(1, 1, (1LL << 17), x+1, y+1);
	ca[0] = caquery(1, 1, (1LL << 17), x+1, y+1);
	ca[1] = acquery(1, 1, (1LL << 17), x+1, y+1);
	
	int cnt = 0;
	if (at[0] > at[1]) {
		cnt += at[1];
		at[0] -= at[1]; 
		at[1] = 0;
	} else {
		cnt += at[0];
		at[1] -= at[0];
		at[0] = 0;
	}
	if (tc[0] > tc[1]) {
		cnt += tc[1];
		tc[0] -= tc[1]; 
		tc[1] = 0;
	} else {
		cnt += tc[0];
		tc[1] -= tc[0];
		tc[0] = 0;
	}
	if (ca[0] > ca[1]) {
		cnt += ca[1];
		ca[0] -= ca[1]; 
		ca[1] = 0;
	} else {
		cnt += ca[0];
		ca[1] -= ca[0];
		ca[0] = 0;
	}
	cnt += (2*(at[0]+at[1]+tc[0]+tc[1]+ca[0]+ca[1]))/3;
	return cnt;
}

// int main() {
	// string aa, bb; cin >> aa >> bb;
void init(string aa, string bb) {
	a = aa; b = bb; n = a.size(); 
	for (int i = 0; i < 3; i++) {
		as[i].resize(n); bs[i].resize(n); 
	}
	if (a[0] == 'A') as[0][0]++;
	if (b[0] == 'A') bs[0][0]++;
	if (a[0] == 'T') as[1][0]++;
	if (b[0] == 'T') bs[1][0]++;
	if (a[0] == 'C') as[2][0]++;
	if (b[0] == 'C') bs[2][0]++;
	for (int i = 1; i < n; i++) {
		for (int j = 0; j < 3; j++) {
			as[j][i] = as[j][i-1];
			bs[j][i] = bs[j][i-1];
		}
		if (a[i] == 'A') as[0][i]++;
		if (b[i] == 'A') bs[0][i]++;
		if (a[i] == 'T') as[1][i]++;
		if (b[i] == 'T') bs[1][i]++;
		if (a[i] == 'C') as[2][i]++;
		if (b[i] == 'C') bs[2][i]++;
	}
	at.assign((1LL << 18), 0LL);
	ta.assign((1LL << 18), 0LL);
	tc.assign((1LL << 18), 0LL);
	ct.assign((1LL << 18), 0LL);
	ca.assign((1LL << 18), 0LL);
	ac.assign((1LL << 18), 0LL);
	for (int i = 0; i < n; i++) {
		if (a[i] == 'A' && b[i] == 'T') {
			atupd(1, 1, (1LL << 17), i+1, 1);
		}
		if (a[i] == 'T' && b[i] == 'C') {
			tcupd(1, 1, (1LL << 17), i+1, 1);
		}
		if (a[i] == 'C' && b[i] == 'A') {
			caupd(1, 1, (1LL << 17), i+1, 1);
		}
		if (a[i] == 'T' && b[i] == 'A') {
			taupd(1, 1, (1LL << 17), i+1, 1);
		}
		if (a[i] == 'C' && b[i] == 'T') {
			ctupd(1, 1, (1LL << 17), i+1, 1);
		}
		if (a[i] == 'A' && b[i] == 'C') {
			acupd(1, 1, (1LL << 17), i+1, 1);
		}
	}
}

#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...