Submission #1289295

#TimeUsernameProblemLanguageResultExecution timeMemory
1289295Ekber_EkberMutating DNA (IOI21_dna)C++20
0 / 100
61 ms20796 KiB
#include "dna.h"
#include <bits/stdc++.h>
#define endl "\n"
#define ff first
#define ss second
#define pb push_back
#define all(v) v.begin(), v.end()
using namespace std;

struct wavelet{
	int mn, mx, nxt=1;
	vector <vector <int>> t, pr;
	vector <int> L, R;
	void init(int mi, int ma) {
		mn = mi, mx = ma;
		t.pb({});
		pr.pb({});
		L.pb(-1);
		R.pb(-1);
	}
	void build(int v, int tl, int tr, vector <int> &a) {
		int tm = (tl + tr) / 2;
		if (v == 1) {
			t.pb({});
			for (int i = 0; i < a.size(); i++) t[v].pb(a[i]);
		}
		while (pr.size() <= v) pr.pb({});
		pr[v].pb(0);
		for (int i = 0; i < t[v].size(); i++) {
			if (t[v][i] <= tm) pr[v].pb(1);
			else pr[v].pb(0);
		}
		for (int i = 1; i < pr[v].size(); i++) pr[v][i] += pr[v][i-1];
		if (tl == tr) return;
		while (L.size() <= v) L.pb(-1);
		while (R.size() <= v) R.pb(-1);
		L[v] = ++nxt;
		R[v] = ++nxt;
		while (t.size() <= R[v]) t.pb({});
		for (int i = 0; i < t[v].size(); i++) {
			if (t[v][i] <= tm) t[L[v]].pb(t[v][i]);
			else t[R[v]].pb(t[v][i]);
		}
		if (t[L[v]].size()) build(L[v], tl, tm, a);
		if (t[R[v]].size()) build(R[v], tm+1, tr, a);
	}
	void bld(vector <int> &v) { build(1, mn, mx, v); }
	int findk(int v, int tl, int tr, int l, int r, int k) {
		if (tl == tr) return tl;
		int tm = (tl + tr) / 2;
		int ct = pr[v][r+1] - pr[v][l];
		if (ct >= k) return findk(L[v], tl, tm, pr[v][l], pr[v][r+1] - 1, k);
		else return findk(R[v], tm+1, tr, l - pr[v][l], r - pr[v][r+1], k - ct);
	}
	int kth(int l, int r, int k) { return findk(1, mn, mx, l, r, k); }
	int findsmallerk(int v, int tl, int tr, int l, int r, int k) {
		if (l > r) return 0;
		if (tl == tr) return r - l + 1;
		int tm = (tl + tr) / 2;
		if (k <= tm) {
			return findsmallerk(L[v], tl, tm, pr[v][l], pr[v][r+1] - 1, k);
		}
		else {
			return findsmallerk(R[v], tm+1, tr, l - pr[v][l], r - pr[v][r+1], k) + pr[v][r+1] - pr[v][l];
		}
	}
	int smallk(int l, int r, int k) { return findsmallerk(1, mn, mx, l, r, k); }
	int findbiggerk(int v, int tl, int tr, int l, int r, int k) {
		if (l > r) return 0;
		if (tl == tr) return r - l + 1;
		int tm = (tl + tr) / 2;
		if (k <= tm) {
			return findbiggerk(L[v], tl, tm, pr[v][l], pr[v][r+1] - 1, k) + r - l + 1 - pr[v][r+1] + pr[v][l];
		}
		else {
			return findbiggerk(R[v], tm+1, tr, l - pr[v][l], r - pr[v][r+1], k);
		}
	}
	int bigk(int l, int r, int k) { return findbiggerk(1, mn, mx, l, r, k); }
};

vector <int> pr1[3], pr2[3], is;
wavelet t;
vector <int> l;

void init(string a, string b) {
	int n = a.size();
	for (int i = 0; i < 3; i++) {
		pr1[i].assign(n, 0);
		pr2[i].assign(n, 0);
	}
	is.assign(n, 0);
	for (int i = 0; i < n; i++) {
		if (a[i] == 'A') pr1[0][i]++;
		else if (a[i] == 'T') pr1[1][i]++;
		else pr1[2][i]++;
		if (b[i] == 'A') pr2[0][i]++;
		else if (b[i] == 'T') pr2[1][i]++;
		else pr2[2][i]++;
	}
	for (int i = 0; i < n; i++) {
		if (a[i] != b[i]) is[i]++;
	}
	map <pair<char, char>, vector <int>> m;
	vector <pair<int, int>> rn;
	for (int i = 0; i < n; i++) {
		if (a[i] == b[i]) continue;
		if (m[{b[i], a[i]}].size()) {
			rn.pb({m[{b[i], a[i]}].back(), i});
			m[{b[i], a[i]}].pop_back();
		}
		else m[{a[i], b[i]}].pb(i);
	}
	sort(all(rn));
	vector <int> r;
	for (auto &i : rn) {
		l.pb(i.ff);
		r.pb(i.ss);
	}
	t.init(0, n);
	t.bld(r);
}

int get_distance(int x, int y) {
	for (int i = 0; i < 3; i++) {
		int a = pr1[i][y] - (x == 0 ? 0 : pr1[i][x-1]);
		int b = pr2[i][y] - (x == 0 ? 0 : pr2[i][x-1]);
		if (a != b) return -1;
	}
	int res = is[y] - (x == 0 ? 0 : is[x-1]);
	int id = lower_bound(all(l), x) - l.begin();
	return res - t.smallk(id, l.size()-1, y);
}
#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...