Submission #1291142

#TimeUsernameProblemLanguageResultExecution timeMemory
1291142kustov_vadim_533Horses (IOI15_horses)C++20
54 / 100
1600 ms103092 KiB
#include <iostream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <set>
#include <queue>
#include <array>
#include <map>
#include <random>
#include <bitset>
#include <stack>
#include <deque>
#include <random>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <chrono>

using namespace std;

typedef long long ll;
typedef long double ld;

mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());

const int M = 1e9 + 7;

struct obj {
	int x = 1;
	ld dx = 1;

	int ry = -1;
	obj() = default;
	obj(int x_, int y_, int i) {
		x = x_;
		dx = x_;
		if (y_ > 1) {
			ry = i;
		}
	}
};


obj merge(obj a, obj b) {
	obj c;
	c.x = (a.x * 1ll * b.x) % M;
	c.dx = a.dx * b.dx;
	c.ry = max(a.ry, b.ry);
	return c;
}


vector<pair<int, int>> a;
vector<obj> tree;

obj get(int v, int l, int r, int ql, int qr) {
	if (l >= qr || ql >= r) return obj();
	if (l >= ql && r <= qr) return tree[v];

	int m = (l + r) / 2;
	obj r1 = get(v * 2, l, m, ql, qr);
	obj r2 = get(v * 2 + 1, m, r, ql, qr);
	return merge(r1, r2);
}

int n;
int solve() {
	int mx = n - 1;

	int r = n;
	while (get(1, 0, n, r, n).dx <= 2e9 && r >0) {
		int i = get(1, 0, n, 0, r).ry;
		r = i;

		if (i == -1) break;

		obj ds = get(1, 0, n, i + 1, mx + 1);
		if (ds.dx * a[mx].second < a[i].second) {
			mx = i;
		}
	}
	return (get(1, 0, n, 0, mx + 1).x * 1ll * a[mx].second) % M;
}

void build(int v, int l, int r) {
	if (r - l == 1) {
		tree[v] = obj(a[l].first, a[l].second, l);
		return;
	}
	int m = (l + r) / 2;
	build(v * 2, l, m);
	build(v * 2 + 1, m, r);
	tree[v] = merge(tree[v * 2], tree[v * 2 + 1]);
}

int init(int N, int X[], int Y[]) {
	tree.resize(4 * N);
	n = N;

	a.resize(N);

	for (int i = 0; i < N; ++i) {
		a[i].first = X[i];
		a[i].second = Y[i];
	}
	build(1, 0, N);
	return solve();
}

void upd(int v, int l, int r, int qi) {
	if (r - l == 1) {
		tree[v] = obj(a[l].first, a[l].second, l);
		return;
	}
	int m = (l + r) / 2;
	if (qi < m) upd(v * 2, l, m, qi);
	else upd(v * 2 + 1, m, r, qi);
	tree[v] = merge(tree[v * 2], tree[v * 2 + 1]);
}

int updateX(int pos, int val) {
	a[pos].first = val;
	upd(1, 0, n, pos);
	return solve();
}


int updateY(int pos, int val) {
	a[pos].second = val;
	upd(1, 0, n, pos);
	return solve();
}
#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...