Submission #297706

#TimeUsernameProblemLanguageResultExecution timeMemory
297706cfalas말 (IOI15_horses)C++14
57 / 100
1544 ms127184 KiB
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include "horses.h"
using namespace std;

#define FORi(i,a,b) for(int i=a;i<b;i++)
#define MOD 1000000007
#define FOR(i,n) FORi(i,0,n)

#define ll long long
#define MID ((l+r)/2)
#define len(x) ((int)((x).size()))

template<typename T>
struct seg_tree{
	struct node{
		T val;
		node* left=NULL;
		node* right=NULL;
		node() {val=0, left=NULL, right=NULL;}
		node(T v) {val=v, right=NULL, left=NULL;}
	};
	static inline node *root=NULL;
	static inline int N;
	const int RAND_VALUE=1;
	seg_tree(int n){N=n, root = new node();}
	seg_tree(){root = new node();}

	inline void merge(node *par){
		par->val = max(par->left->val , par->right->val);
	}

	inline void update_node(node* ind, int val){
		ind->val = val;
	}

	void build(vector<T>& arr, int l=0, int r=N-1, node *ind=root){
		if(l==r) ind->val = arr[l];
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();
			build(arr,l,MID,ind->left);
			build(arr,MID+1,r,ind->right);

			merge(ind);
		}
	}

	void update(int rl, int rr, int val, int l=0, int r=N-1, node* ind=root){
		if(rl<=l && r<=rr) update_node(ind, val);
		else if(rr<l || r<rl) return;
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();
			update(rl,rr,val,l,MID,ind->left);
			update(rl,rr,val,MID+1,r,ind->right);
			merge(ind);
		}
	}

	T query(int rl, int rr, int l=0, int r=N-1, node* ind=root){
		if(rl<=l && r<=rr) return ind->val;
		else if(rl>r || l>rr) return RAND_VALUE;
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();

			T ret=0;
			ret = max(ret, query(rl,rr,l,MID,ind->left));
			ret = max(ret, query(rl,rr,MID+1,r,ind->right));
			return ret;
		}
	}
};

template<typename T>
struct mult_seg_tree{
	struct node{
		T val;
		node* left=NULL;
		node* right=NULL;
		node() {val=0, left=NULL, right=NULL;}
		node(T v) {val=v, right=NULL, left=NULL;}
	};
	static inline node *root=NULL;
	static inline int N;
	const int RAND_VALUE=1;
	mult_seg_tree(int n){N=n, root = new node();}
	mult_seg_tree(){root = new node();}

	inline void merge(node *par){
		par->val = par->left->val * par->right->val;
	}

	inline void update_node(node* ind, int val){
		ind->val = val;
	}

	void build(vector<int>& arr, int l=0, int r=N-1, node *ind=root){
		if(l==r) ind->val = arr[l];
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();
			build(arr,l,MID,ind->left);
			build(arr,MID+1,r,ind->right);

			merge(ind);
		}
	}

	void update(int rl, int rr, int val, int l=0, int r=N-1, node* ind=root){
		if(rl<=l && r<=rr) update_node(ind, val);
		else if(rr<l || r<rl) return;
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();
			update(rl,rr,val,l,MID,ind->left);
			update(rl,rr,val,MID+1,r,ind->right);
			merge(ind);
		}
	}

	T query(int rl, int rr, int l=0, int r=N-1, node* ind=root){
		if(rl<=l && r<=rr) return ind->val;
		else if(rl>r || l>rr) return RAND_VALUE;
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();

			T ret=RAND_VALUE;
			ret *= query(rl,rr,l,MID,ind->left);
			ret *= query(rl,rr,MID+1,r,ind->right);
			return ret;
		}
	}
};

template<typename T>
struct mult_mod_seg_tree{
	struct node{
		T val;
		node* left=NULL;
		node* right=NULL;
		node() {val=0, left=NULL, right=NULL;}
		node(T v) {val=v, right=NULL, left=NULL;}
	};
	static inline node *root=NULL;
	static inline int N;
	const int RAND_VALUE=1;
	mult_mod_seg_tree(int n){N=n, root = new node();}
	mult_mod_seg_tree(){root = new node();}

	inline void merge(node *par){
		par->val = (((ll)par->left->val) * ((ll)par->right->val)) % MOD;
	}

	inline void update_node(node* ind, int val){
		ind->val = val;
	}

	void build(vector<int>& arr, int l=0, int r=N-1, node *ind=root){
		if(l==r) ind->val = arr[l];
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();
			build(arr,l,MID,ind->left);
			build(arr,MID+1,r,ind->right);

			merge(ind);
		}
	}

	void update(int rl, int rr, int val, int l=0, int r=N-1, node* ind=root){
		if(rl<=l && r<=rr) update_node(ind, val);
		else if(rr<l || r<rl) return;
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();
			update(rl,rr,val,l,MID,ind->left);
			update(rl,rr,val,MID+1,r,ind->right);
			merge(ind);
		}
	}

	T query(int rl, int rr, int l=0, int r=N-1, node* ind=root){
		if(rl<=l && r<=rr) return ind->val;
		else if(rl>r || l>rr) return RAND_VALUE;
		else{
			if(ind->left==NULL) ind->left = new node();
			if(ind->right==NULL) ind->right = new node();

			ll ret=RAND_VALUE;
			ret *= query(rl,rr,l,MID,ind->left);
			ret%=MOD;
			ret *= query(rl,rr,MID+1,r,ind->right);
			ret%=MOD;
			return ret;
		}
	}
};

typedef vector<int> vi;
vi x;
vector<int> y;
vector<double> a;
set<int> xx;

clock_t start_timer;
void time_start(){
	start_timer = clock();
}
void time_end(){
	auto endt = clock();
	//cout<<(double)(endt-start_timer) / CLOCKS_PER_SEC<<endl;
}

seg_tree<int> yseg;
mult_seg_tree<double> xsegd;
mult_mod_seg_tree<int> xsegm;
#define FOA(v,qq) for(auto v : qq)
int get_ans(){
	auto it = xx.end();
	it--;
	it--;
	int cnt=0;
	double maxa=0;
	int maxapos=-1, next=-1;

	// O(30)
	auto itt = xx.end();
	ll pp=1;
	auto st = it;
	auto vv = yseg.query(0,yseg.N-1);
	while(itt!=xx.begin() && pp<vv) itt--, pp*=x[*itt], st=itt;

	int f = *itt;
	// O(30logN)
	while(1){
		auto it2 = it;
		it2++;
		// O(logN)
		double c = xsegd.query(f, *it);
		assert(c>0);

		// O(logN)
		c*=(double)yseg.query(*it, *it2-1);
		//cout<<c<<endl;
		if(c>maxa){
			maxa = c;
			maxapos = *it;
			next = *it2;
		}
		cnt++;
		if(it==st) break;
		it--;
	}
	// O(logN)
	int c = xsegm.query(0, maxapos);
	c= ((ll) c * (ll) yseg.query(maxapos, next-1) ) %MOD;
	return c;
}


int init(int N, int X[], int Y[]) {
	time_start();
	x.resize(N+1);
	y.resize(N);
	FOR(i,N) x[i] = X[i], y[i] = Y[i];
	x[N] = 1;

	yseg.N = N;
	yseg.build(y);

	xsegd.N = N;
	xsegd.build(x);

	xsegm.N = N;
	xsegm.build(x);

	FOR(i,N){
		if(x[i]>1) xx.insert(i);
	}
	xx.insert(N);
	xx.insert(0);
	time_end();
	time_start();
	get_ans();
	time_end();
	return get_ans();
}

int cc=0;
int updateX(int pos, int val) {	
	cc++;
	if(x[pos]==val) return get_ans();
	if(val==1 && x[pos]!=1) xx.erase(pos);
	else if(x[pos]==1 && val!=1) xx.insert(pos);
	x[pos] = val;
	xsegd.update(pos, pos, x[pos]);
	xsegm.update(pos, pos, x[pos]);
	int anss = get_ans();
	return anss;
}

int updateY(int pos, int val) {
	cc++;
	yseg.update(pos, pos, val);
	y[pos] = val;
	int anss = get_ans();
	return anss;
}

Compilation message (stderr)

horses.cpp:24:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
   24 |  static inline node *root=NULL;
      |         ^~~~~~
horses.cpp:25:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
   25 |  static inline int N;
      |         ^~~~~~
horses.cpp:86:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
   86 |  static inline node *root=NULL;
      |         ^~~~~~
horses.cpp:87:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
   87 |  static inline int N;
      |         ^~~~~~
horses.cpp:148:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
  148 |  static inline node *root=NULL;
      |         ^~~~~~
horses.cpp:149:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
  149 |  static inline int N;
      |         ^~~~~~
horses.cpp: In function 'void time_end()':
horses.cpp:214:7: warning: unused variable 'endt' [-Wunused-variable]
  214 |  auto endt = clock();
      |       ^~~~
horses.cpp: In function 'int get_ans()':
horses.cpp:260:50: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  260 |  c= ((ll) c * (ll) yseg.query(maxapos, next-1) ) %MOD;
      |                                                  ^
horses.cpp: In instantiation of 'T mult_mod_seg_tree<T>::query(int, int, int, int, mult_mod_seg_tree<T>::node*) [with T = int]':
horses.cpp:259:32:   required from here
horses.cpp:198:11: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  198 |    return ret;
      |           ^~~
horses.cpp: In instantiation of 'void mult_mod_seg_tree<T>::merge(mult_mod_seg_tree<T>::node*) [with T = int]':
horses.cpp:170:4:   required from 'void mult_mod_seg_tree<T>::build(std::vector<int>&, int, int, mult_mod_seg_tree<T>::node*) [with T = int]'
horses.cpp:279:15:   required from here
horses.cpp:155:61: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  155 |   par->val = (((ll)par->left->val) * ((ll)par->right->val)) % MOD;
      |                                                             ^
#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...