Submission #1302320

#TimeUsernameProblemLanguageResultExecution timeMemory
1302320nicolo_010Horses (IOI15_horses)C++20
17 / 100
1597 ms75528 KiB
#include <bits/stdc++.h>
#include "horses.h"
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
const int MOD = 1e9+7;

const ll INF = 1e18;

vector<ll> x;
vector<ll> y;
int n;

struct SegTree {
	vector<ll> tree;
	SegTree() {
	}

	void init(int m) {
		tree.assign(4*m, 0);
	}

	void query(int p, int l, int r, int i, int x) {
		if (l > i || r < i) return;
		if (l==r) {
			tree[p] = x;
		}
		else {
			int m = (l+r)/2;
			query(2*p, l, m, i, x);
			query(2*p+1, m+1, r, i, x);
			ll i1 = tree[2*p];
			ll i2 = tree[2*p+1];
			tree[p] = (i1*i2) % MOD;
		}
	}
	ll rsq(int p, int l, int r, int i, int j) {
		if (l > j || r < i) return 1;
		if (i <= l && r <= j) {
			return tree[p];
		}
		else {
			int m = (l+r)/2;
			ll i1 = rsq(2*p, l, m, i, j);
			ll i2 = rsq(2*p+1, m+1, r, i, j);
			return (i1*i2)%MOD;
		}
	}

	void querymx(int p, int l, int r, int i, int x) {
		if (l > i || r < i) return;
		if (l == r) {
			tree[p] = x;
		}
		else {
			int m = (l+r)/2;
			querymx(2*p, l, m, i, x);
			querymx(2*p+1, m+1, r, i, x);
			int i1 = tree[2*p];
			int i2 = tree[2*p+1];
			tree[p] = max(i1, i2);
		}
	}

	int rmq(int p, int l, int r, int i, int j) {
		if (l > j || r < i) return 0;
		if (i <= l && r <= j) {
			return tree[p];
		}
		else {
			int m = (l+r)/2;
			int i1 = rmq(2*p, l, m, i, j);
			int i2 = rmq(2*p+1, m+1, r, i, j);
			return max(i1, i2);
		}
	}


};
SegTree st, mxtr;

struct SegTreelazy {
	vector<int> tree;
	vector<int> lazy;
	SegTreelazy() {

	}

	void init(int m) {
		tree.assign(4*m, 0);
		lazy.assign(4*m, -1);
	}

	void prop(int p, int l, int r) {
		tree[p] = lazy[p];
		if (l != r) {
			lazy[2*p] = lazy[p];
			lazy[2*p+1] = lazy[p];
		}
		lazy[p] = -1;
	}

	void query(int p, int l, int r, int i, int j, int x) {
		if (l > j || r < i) return;
		if (i <= l && r <= j) {
			lazy[p] = x;
			prop(p, l, r);
		}
		else {
			if (lazy[p] != -1) {
				prop(p, l, r);
			}
			int m = (l+r)/2;
			query(2*p, l, m, i, j, x);
			query(2*p+1, m+1, r, i, j, x);
		}
	}

	int in(int p, int l, int r, int i) {
		if (l > i || r < i) return 0;
		if (lazy[p] != -1) prop(p, l, r);
		if (l==r) {
			return tree[p];
		}
		else {
			int m = (l+r)/2;
			int i1 = in(2*p, l, m, i);
			int i2 = in(2*p+1, m+1, r, i);
			return i1+i2;
		}
	}
};

SegTreelazy nx, pr;

ll compute() {
	int m = x.size();
	int idx=pr.in(1, 0, n, m);
	for (int i=0; i<40; i++) {
		idx = pr.in(1, 0, n, idx);
	}
	ll prod = 1;
	bool moduled=false;
	int cnt=0;
	for (int i = nx.in(1, 0, n-1, idx); i<n; i=nx.in(1, 0, n-1, i)) {
		if (cnt > 50) break;
		cnt++;
		int nxtid = nx.in(1, 0, n-1, idx);
		int nxti = nx.in(1, 0, n-1, i);
		ll y0 = mxtr.rmq(1, 0, n-1, idx, nxtid-1);
		ll y1 = mxtr.rmq(1, 0, n-1, i, nxti-1);
		prod *= x[i];
		//cout << idx << " " << i << " " << y0 << " " << y1 << endl;
		if (prod >= MOD) {
			prod %= MOD;
			moduled = true;
		}
		if (moduled) {
			idx = i;
			prod = 1;
			moduled = false;
		}
		else {
			if (prod*y1 >= y0) {
				idx = i;
				prod = 1;
				moduled = false;
			}
		}
	}
	int last = y[idx];
	int nxti = nx.in(1, 0, n-1, idx);
	ll y0 = mxtr.rmq(1, 0, n-1, idx, nxti);
	prod = st.rsq(1, 0, n-1, 0, idx);
	return (prod*y0)%MOD; 
}

int init(int N, int* a, int* b) {
	n = N;
	x.assign(n, 0);
	y.assign(n, 0);
	for (int i=0; i<n; i++) {
		x[i] = a[i];
		y[i] = b[i];
	}
	st.init(n);
	mxtr.init(n);
	for (int i=0; i<n; i++) {
		st.query(1, 0, n-1, i, x[i]);
		mxtr.querymx(1, 0, n-1, i, y[i]);
	}
	pr.init(n+1);
	nx.init(n);
	pr.query(1, 0, n, 0, 0, 0);
	int last = 0;
	nx.query(1, 0, n-1, n-1, n-1, n);
	for (int i=1; i<n; i++) {
		pr.query(1, 0, n-1, i, i, last);
		if (x[i] != 1) {
			last = i;
		}
	}
	pr.query(1, 0, n, n, n, last);
	last = (x[n-1] == 1 ? n : n-1);
	for (int i=n-2; i>=0; i--) {
		nx.query(1, 0, n-1, i, i, last);
		if (x[i] != 1) {
			last = i;
		}
	}
	return compute();
}

int updateX(int pos, int val) {
	st.query(1, 0, n-1, pos, val);
	int prpos = pr.in(1, 0, n, pos);
	int nxpos = nx.in(1, 0, n, pos);
	if (val != 1 && x[pos] == 1 && pos != 0) {
		nx.query(1, 0, n-1, prpos, pos-1, pos);
		pr.query(1, 0, n, pos+1, nxpos, pos);
	}
	else if (val == 1 && x[pos] != 1) {
		nx.query(1, 0, n-1, prpos, pos, nxpos);
		pr.query(1, 0, n, pos, nxpos, prpos);
	}
	x[pos] = val;
	return compute();
}

int updateY(int pos, int val) {
	y[pos] = val;
	mxtr.querymx(1, 0, n-1, pos, val);
	return compute();
}
#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...