제출 #1004976

#제출 시각아이디문제언어결과실행 시간메모리
1004976pawned말 (IOI15_horses)C++17
100 / 100
346 ms57428 KiB
#pragma GCC optimize("O1,O2,O3,Ofast,unroll-loops")

#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define pb push_back
typedef long long ll;
typedef pair<ll, ll> ii;
typedef vector<ll> vi;

#include "horses.h"

const ll MOD = 1e9 + 7;
const ll MAX = 1e9 + 5;
const ll MAX_SZ = 5e5 + 5;

struct Segtree {	// point update, range max query
	int sz;
	vi vals;
	void init(int N) {
		sz = 1;
		while (sz < N)
			sz *= 2;
		vals = vi(2 * sz, 0);
	}
	void upd(int pos, ll val, int id, int left, int right) {
		if (right - left == 1) {
			vals[id] = val;
			return;
		}
		int mid = (left + right) / 2;
		if (pos < mid)
			upd(pos, val, 2 * id + 1, left, mid);
		else
			upd(pos, val, 2 * id + 2, mid, right);
		vals[id] = max(vals[2 * id + 1], vals[2 * id + 2]);
	}
	void upd(int pos, ll val) {
		upd(pos, val, 0, 0, sz);
	}
	ll query(int qleft, int qright, int id, int left, int right) {
		if (qleft <= left && right <= qright)
			return vals[id];
		if (qright <= left || right <= qleft)
			return 0;
		int mid = (left + right) / 2;
		ll s1 = query(qleft, qright, 2 * id + 1, left, mid);
		ll s2 = query(qleft, qright, 2 * id + 2, mid, right);
		return max(s1, s2);
	}
	ll query(int qleft, int qright) {
		return query(qleft, qright, 0, 0, sz);
	}
};

ll norm(ll x) {
	x %= MOD;
	x += MOD;
	x %= MOD;
	return x;
}

ll binpow(ll x, ll y) {
	x = norm(x);
	ll res = 1;
	while (y > 0) {
		if (y % 2 == 1)
			res = norm(res * x);
		x = norm(x * x);
		y /= 2;
	}
	return res;
}

ll inv(ll x) {
	return binpow(x, MOD - 2);
}

int N;

vi X;
vi Y;

Segtree st;

set<int> gp;	// pos of X w/ val > 1

ll prodall = 1;	// product of all X_i

ll solve() {
	auto it = gp.end();
	ll currn = Y[N - 1];
	ll currd = 1;
	ll bestn = currn;
	ll bestd = currd;
	while (it != gp.begin()) {
		it--;
		if (currd > MAX)
			break;
		int p1 = *it;
		int p2 = N;
		if (it != (--gp.end())) {
			auto it2 = it;
			it2++;
			p2 = *it2;
		}
		currn = st.query(p1, p2);
//		cout<<"at "<<p1<<" "<<p2<<endl;
//		cout<<"currn, currd: "<<currn<<" "<<currd<<endl;
		if (currn * bestd > bestn * currd) {
			bestn = currn;
			bestd = currd;
		}
		currd *= X[*it];	// update denominator
	}
//	cout<<"bestn, bestd: "<<bestn<<" "<<bestd<<endl;
	ll ans = norm(prodall * norm(bestn * inv(bestd)));
	return ans;
}

int init(int n, int x[], int y[]) {
	N = n;
	X = vi(N); Y = vi(N);
	for (int i = 0; i < N; i++) {
		X[i] = x[i];
		Y[i] = y[i];
	}
	st.init(N);
	for (int i = 0; i < N; i++) {
		st.upd(i, Y[i]);
	}
/*	cout<<"st: ";
	for (int i = 0; i < st.sz * 2; i++) {
		cout<<st.vals[i]<<" ";
	}
	cout<<endl;*/
	for (int i = 0; i < N; i++) {
		if (X[i] != 1)
			gp.insert(i);
	}
	gp.insert(-1);
	for (int i = 0; i < N; i++) {
		prodall *= X[i];
		prodall = norm(prodall);
	}
	ll ans = solve();
	return (int)(ans);
}

int updateX(int pos, int val) {
	if (X[pos] != 1 && val == 1)
		gp.erase(pos);
	if (X[pos] == 1 && val != 1)
		gp.insert(pos);
	prodall = norm(prodall * inv(X[pos]));
	X[pos] = val;
	prodall = norm(prodall * X[pos]);
	ll ans = solve();
	return (int)(ans);
}

int updateY(int pos, int val) {
	Y[pos] = val;
	st.upd(pos, val);
	ll ans = solve();
	return (int)(ans);
}
#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...