제출 #297715

#제출 시각아이디문제언어결과실행 시간메모리
297715cfalas말 (IOI15_horses)C++17
17 / 100
1557 ms114140 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()))
#define F first
#define S second

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;
		}
	}
};

struct mult_seg_tree{
	struct node{
		double vald;
		int valm;
		node* left=NULL;
		node* right=NULL;
		node() {vald=0, valm=0, left=NULL, right=NULL;}
		node(double v, int m) {vald=v, valm=m,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->vald = par->left->vald * par->right->vald;
		par->valm = (((ll)par->left->valm) * ((ll)par->right->valm)) % MOD;
	}

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

	void build(vector<int>& arr, int l=0, int r=N-1, node *ind=root){
		if(l==r) ind->vald = arr[l], ind->valm = arr[l];//, cout<<l<<" "<<arr[l]<<endl;
		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);
		}
	}

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

			pair<int,double> res1 = query(rl,rr,l,MID,ind->left);
			pair<int,double> res2 = query(rl,rr,MID+1,r,ind->right);

			double ret1 = res1.S * res2.S;
			ll ret2=res1.F * res2.F;
			ret2%=MOD;
			return make_pair(ret2, ret1);
		}
	}
};

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 xseg;
#define FOA(v,qq) for(auto v : qq)
int get_ans(){
	auto it = xx.end();
	it--;
	it--;
	int cnt=0;
	double maxa=0;
	int ansa=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;
	//cout<<f<<endl;
	// O(30logN)
	while(1){
		auto it2 = it;
		it2++;
		// O(logN)
		//cout<<*it<<" "<<*it2<<endl;
		pair<int,double> res = xseg.query(f, *it);
		double c = res.S;
		assert(c>0);

		// O(logN)
		int res2 = yseg.query(*it, *it2-1);
		//cout<<c<<" ";
		c*=res2;
		//cout<<c<<endl;
		if(c>maxa){
			maxa = c;
			ansa = (((ll)res.F) * ((ll)res2)) % MOD;
		}
		cnt++;
		if(it==st) break;
		it--;
	}
	ansa = (((ll)xseg.query(0, f-1).F) * ansa) % MOD;
	return ansa;
}


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);

	xseg.N = N+1;
	xseg.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;
	xseg.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;
	//cout<<"--\n";
	int anss = get_ans();
	return anss;
}

컴파일 시 표준 에러 (stderr) 메시지

horses.cpp: In member function 'void mult_seg_tree::merge(mult_seg_tree::node*)':
horses.cpp:96:64: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
   96 |   par->valm = (((ll)par->left->valm) * ((ll)par->right->valm)) % MOD;
      |                                                                ^
horses.cpp: In function 'void time_end()':
horses.cpp:157:7: warning: unused variable 'endt' [-Wunused-variable]
  157 |  auto endt = clock();
      |       ^~~~
horses.cpp: In function 'int get_ans()':
horses.cpp:198:38: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  198 |    ansa = (((ll)res.F) * ((ll)res2)) % MOD;
      |                                      ^
horses.cpp:204:45: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  204 |  ansa = (((ll)xseg.query(0, f-1).F) * ansa) % 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...