This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "horses.h"
#include <bits/stdc++.h>
using namespace std;
#define FAST_IO ios_base::sync_with_stdio(0); cin.tie(nullptr)
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define REP(n) FOR(O, 1, (n))
#define f first
#define s second
#define pb push_back
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vii;
typedef vector<ll> vl;
const int MAXN = 500100;
const ll MOD = 1e9+7;
ll pwr (ll a, ll p) {
if (p == 0) return 1;
if (p == 1) return a%MOD;
ll ret = pwr(a, p/2);
ret = (ret*ret)%MOD;
if (p%2 == 1) ret = (ret*(a%MOD))%MOD;
return ret%MOD;
}
ll modInv (ll a) {
return pwr(a%MOD, MOD-2);
}
ll fen[MAXN];
void updPref (int p, ll x) {
for (int i = p; i < MAXN; i += i&(-i))
fen[i] = (fen[i]*x)%MOD;
}
ll prefX (int p) {
ll ret = 1;
for (int i = p; i > 0; i -= i&(-i))
ret = (ret * fen[i])%MOD;
return ret;
}
int n;
ll x[MAXN], y[MAXN];
ll tree2[4*MAXN];
void upd2 (int p, ll val, int id = 1, int le = 1, int ri = n) {
if (le == ri){
tree2[id] = val;
return;
}
int mid = (le+ri)/2;
if (p <= mid)
upd2(p, val, 2*id, le, mid);
else
upd2(p, val, 2*id+1, mid+1, ri);
tree2[id] = tree2[2*id] + tree2[2*id+1];
}
ll get2 (int fr, int to, int id = 1, int le = 1, int ri = n) {
if (fr > ri || to < le) return 0;
if (fr <= le && ri <= to) return tree2[id];
int mid = (le+ri)/2;
return get2(fr, to, 2*id, le, mid) + get2(fr, to, 2*id+1, mid+1, ri);
}
ll get2 (int p) {
return get2(1, p);
}
int getId (ll sum, int id = 1, int le = 1, int ri = n) {
if (le == ri) return le;
int mid = (le+ri)/2;
if (sum <= tree2[2*id]) return getId(sum, 2*id, le, mid);
else return getId(sum-tree2[2*id], 2*id+1, mid+1, ri);
}
ll tree[4*MAXN];
void updTree (int p, ll val, int id = 1, int le = 1, int ri = n) {
if (le == ri){
tree[id] = le;
return;
}
int mid = (le+ri)/2;
if (p <= mid)
updTree(p, val, 2*id, le, mid);
else
updTree(p, val, 2*id+1, mid+1, ri);
if (y[tree[2*id]] > y[tree[2*id+1]])
tree[id] = tree[2*id];
else
tree[id] = tree[2*id+1];
}
ll getMaxY (int fr, int to, int id = 1, int le = 1, int ri = n) {
if (fr > ri || to < le) return 0;
if (fr <= le && ri <= to) return tree[id];
int mid = (le+ri)/2;
ll id1 = getMaxY(fr, to, 2*id, le, mid);
ll id2 = getMaxY(fr, to, 2*id+1, mid+1, ri);
if (y[id1] > y[id2]) return id1;
else return id2;
}
void print (){
FOR(i, 1, n) {
cout << " i = " << i << endl;
cout << " x = " << x[i] << " y = " << y[i] << endl;
cout << " prefX = " << prefX(i) << endl;
cout << " get2 pref = " << get2(i) << " get2 i = " << get2(i,i) << endl;
cout << " maxY i = " << getMaxY(i, i) << " getMaxY pref = " << getMaxY(1, i) << endl;
}
}
ll getMax () {
int id = 1;
if (get2(1, n) > 35) {
id = n;
REP(30) {
if (get2(id, id) > 0) id--;
else {
int le = 1, ri = id-1;
while (le < ri) {
int mid = (le+ri+1)/2;
if(get2(mid, id) == 0) ri = mid-1;
else le = mid;
}
id = le-1;
}
}
}
ll cr = 1;
FOR(i, id+1, n) {
//cout << " i = " << i << " id = " << id << endl;
if (x[i] > 1) {
cr *= x[i];
if (cr * y[i] > y[id]) {
id = i;
cr = 1;
}
//cout << " case xi > 1, id = " << id << endl;
} else {
int le = i;
if (get2(le,n) == 0) le = n;
else {
ll sm = i > 1 ? get2(1, i-1) : 0;
sm++;
le = getId(sm)-1;
}
/// [i;le] all x are equal to 1
int mxId = getMaxY(i, le);
// cout << " case xi = 1, le = " << le << endl;
if (cr * y[mxId] > y[id]) {
id = mxId;
cr = 1;
}
i = le;
// cout << " id = " << id << " i = " << i << endl;
}
}
//cout << " final id = " << id << endl;
ll ret = (prefX(id) * y[id])%MOD;
//cout << " prefX = " << prefX(id) << " y = " << y[id] << endl;
//print();
return ret;
}
int init(int N, int X[], int Y[]) {
n = N;
FOR(i, 1, n) x[i] = X[i-1];
FOR(i, 1, n) y[i] = Y[i-1];
FOR(i, 0, MAXN-1) fen[i] = 1;
FOR(i, 1, n) updPref (i, x[i]);
FOR(i, 1, n) if (x[i] > 1) upd2(i, 1);
FOR(i, 1, n) updTree(i, y[i]);
return getMax();
}
int updateX(int pos, int val) {
pos++;
updPref (pos, modInv(x[pos]));
if (x[pos] > 1) upd2(pos, -1);
x[pos] = val;
updPref (pos, x[pos]);
if (x[pos] > 1) upd2(pos, 1);
return getMax();
}
int updateY(int pos, int val) {
pos++;
y[pos] = val;
updTree(pos, y[pos]);
return getMax();
}
Compilation message (stderr)
horses.cpp: In function 'll getMax()':
horses.cpp:159:31: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
159 | int mxId = getMaxY(i, le);
| ~~~~~~~^~~~~~~
horses.cpp: In function 'int init(int, int*, int*)':
horses.cpp:189:15: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
189 | return getMax();
| ~~~~~~^~
horses.cpp: In function 'int updateX(int, int)':
horses.cpp:199:15: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
199 | return getMax();
| ~~~~~~^~
horses.cpp: In function 'int updateY(int, int)':
horses.cpp:206:15: warning: conversion from 'll' {aka 'long long int'} to 'int' may change value [-Wconversion]
206 | return getMax();
| ~~~~~~^~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |