Submission #288258

#TimeUsernameProblemLanguageResultExecution timeMemory
288258DystoriaX말 (IOI15_horses)C++14
57 / 100
1586 ms29944 KiB
#include "horses.h"
#include <algorithm>
#include <vector>
#include <iostream>
#include <assert.h>

#define lc (i << 1)
#define rc (1 | (i << 1))

using namespace std;

const int MOD = 1e9 + 7;

int add(long long a, long long b){
	return (a + b) % MOD;
}

int mul(long long a, long long b){
	return (a * b) % MOD;
}

struct Node{
	int val, mx;

	Node(){
		val = mx = 0;
	}
};

Node st[4 * 500010];
long long bit[500010];
int vis[500010];
long long vs[500010];

int op = 0;

int n;
vector<int> x, y;
const int MAX = 1e9;

void updateBIT(int x, int val){
	for(; x <= n; x += x & (-x)) bit[x] += val;
}

long long qs(int x){
	if(vis[x] == op) return vs[x];

	long long ret = 0;
	for(; x; x -= x & (-x)) ret += bit[x];
	
	vs[x] = ret;
	vis[x] = op;
	return ret;
}

long long qs(int l, int r){
	if(r < l) return 0;
	return qs(r) - qs(l - 1);
}

void update(int l, int r, int pt, int val, int type, int i){
	if(r < pt || pt < l) return;

	if(l == r && l == pt){
		if(type == 0) st[i].val = val;
		else st[i].mx = val;

		return;
	}

	int m = (l + r) >> 1;

	update(l, m, pt, val, type, lc);
	update(m + 1, r, pt, val, type, rc);

	st[i].val = mul(st[lc].val, st[rc].val);
	st[i].mx = max(st[lc].mx, st[rc].mx);
}

int query(int l, int r, int ls, int rs, int i){
	if(r < ls || rs < l) return 1;

	if(ls <= l && r <= rs) return st[i].val;

	int m = (l + r) >> 1;

	return mul(query(l, m, ls, rs, lc), query(m + 1, r, ls, rs, rc));
}

long long queryMax(int l, int r, int ls, int rs, int i){
	if(r < ls || rs < l) return 0;

	if(ls <= l && r <= rs) return st[i].mx;

	int m = (l + r) >> 1;

	return max(queryMax(l, m, ls, rs, lc), queryMax(m + 1, r, ls, rs, rc));
}

int GetPrev(int idx){
	int l = 0, r = idx;
	while(l <= r){
		int m = (l + r) >> 1;

		// We find at interval [m, idx - 1], the sum should be equal to idx - m
		if(qs(m + 1, idx) == idx - m) r = m - 1;
		else l = m + 1;
	}

	return l;
}

int GetValue(){
	++op;
	int idx = 0;

	long long pr = 1;

	vector<int> path;
	path.emplace_back(n);
	for(idx = n - 1; idx >= 0; idx = GetPrev(idx) - 1){
		pr *= x[idx];

		if(pr > MAX) break;
		if(x[idx] != 1) path.emplace_back(idx);
	}

	idx = max(idx, 0);

	pr = 1;
	int optVal = 0, opt = 0;

	int counter  = 0;

	while(true){
		counter++;
		assert(counter < 100);

		int nxt = path.back() - 1; path.pop_back();

		pr *= x[idx];

		int yval = queryMax(0, n - 1, idx, nxt, 1);

		if(optVal < pr * yval){
			opt = idx;
			optVal = yval;
			pr = 1;
		}

		idx = nxt + 1;

		if(idx == n) break;
	}

	return mul(query(0, n - 1, 0, opt, 1), optVal);
}

int init(int N, int X[], int Y[]) {
	n = N;
	x.insert(x.begin(), X, X + N);
	y.insert(y.begin(), Y, Y + N);

	for(int i = 0; i < n; i++) update(0, n - 1, i, x[i], 0, 1), updateBIT(i + 1, x[i]);
	for(int i = 0; i < n; i++) update(0, n - 1, i, y[i], 1, 1);

	// for(int i = 0; i < n; i++){
	// 	cerr << i << " with previous: " << GetPrev(i) << "\n";
	// }

	return GetValue();
}

int updateX(int pos, int val) {	
	updateBIT(pos + 1, -x[pos]);
	x[pos] = val;
	updateBIT(pos + 1, val);
	update(0, n - 1, pos, val, 0, 1);

	return GetValue();
}

int updateY(int pos, int val) {
	y[pos] = val;
	update(0, n - 1, pos, val, 1, 1);

	return GetValue();
}

Compilation message (stderr)

horses.cpp: In function 'int add(long long int, long long int)':
horses.cpp:15:17: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
   15 |  return (a + b) % MOD;
      |         ~~~~~~~~^~~~~
horses.cpp: In function 'int mul(long long int, long long int)':
horses.cpp:19:17: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
   19 |  return (a * b) % MOD;
      |         ~~~~~~~~^~~~~
horses.cpp: In function 'void updateBIT(int, int)':
horses.cpp:41:30: warning: declaration of 'x' shadows a global declaration [-Wshadow]
   41 | void updateBIT(int x, int val){
      |                              ^
horses.cpp:38:13: note: shadowed declaration is here
   38 | vector<int> x, y;
      |             ^
horses.cpp: In function 'long long int qs(int)':
horses.cpp:45:19: warning: declaration of 'x' shadows a global declaration [-Wshadow]
   45 | long long qs(int x){
      |                   ^
horses.cpp:38:13: note: shadowed declaration is here
   38 | vector<int> x, y;
      |             ^
horses.cpp: In function 'int GetValue()':
horses.cpp:143:22: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  143 |   int yval = queryMax(0, n - 1, idx, nxt, 1);
      |              ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#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...