이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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, int l, int r){
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,l,r);
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 += query(rl,rr,l,MID,ind->left);
ret += query(rl,rr,MID+1,r,ind->right);
return ret;
}
}
};
template<typename T>
struct mult_seg_tree{
struct node{
T val;
T laz;
int left=-1;
int right=-1;
node() {val=1, laz=0, left=-1, right=-1;}
node(T v) {val=v, laz=0, right=-1, left=-1;}
};
vector<node> seg;
static inline int N;
const int RAND_VALUE=1;
mult_seg_tree(int n){N=n, seg.assign(1, node());}
mult_seg_tree(){seg.assign(1, node());}
inline node merge(node par, node a, node b){
node ret;
ret.left = par.left, ret.right = par.right;
ret.val = a.val * b.val;
return ret;
}
inline void update_node(int ind, int val, int l, int r){
seg[ind].val = val;
}
inline void down(node &par, int l, int r){
/*
seg[par.left].val += par.laz * (MID-l+1);
seg[par.right].val += par.laz * (r-MID);
seg[par.left].laz = par.laz;
seg[par.right].laz = par.laz;
par.laz = 0;
*/
}
inline void create_children(int ind){
node par = seg[ind];
if(par.left==-1){
//cout<<"left\n";
par.left=seg.size(), seg.push_back(node());
}
if(par.right==-1) par.right=seg.size(), seg.push_back(node());
seg[ind] = par;
}
void build(vector<int>& arr, int l=0, int r=N-1, int ind=0){
if(l==r) seg[ind] = node(arr[l]);
else{
create_children(ind);
build(arr,l,MID,seg[ind].left);
build(arr,MID+1,r,seg[ind].right);
seg[ind] = merge(seg[ind], seg[seg[ind].left], seg[seg[ind].right]);
}
}
void update(int pos, int val, int l=0, int r=N-1, int ind=0){
if(l==r && r==pos) update_node(ind, val,l,r);
else if(pos<l || pos>r || l==r) return;
else{
create_children(ind);
down(seg[ind],l,r);
update(pos,val,l,MID,seg[ind].left);
update(pos,val,MID+1,r,seg[ind].right);
seg[ind] = merge(seg[ind], seg[seg[ind].left], seg[seg[ind].right]);
}
}
node _query(int rl, int rr, int l=0, int r=N-1, int ind=0){
if(rl<=l && r<=rr) return seg[ind];
else if(rl>r || l>rr) return RAND_VALUE;
else{
create_children(ind);
down(seg[ind],l,r);
return merge(seg[ind], _query(rl, rr, l, MID, seg[ind].left), _query(rl,rr,MID+1,r,seg[ind].right));
}
}
T query(int l, int r){
return _query(l,r).val;
}
};
template<typename T>
struct mult_mod_seg_tree{
struct node{
T val;
T laz;
int left=-1;
int right=-1;
node() {val=0, laz=0, left=-1, right=-1;}
node(T v) {val=v, laz=0, right=-1, left=-1;}
};
vector<node> seg;
static inline int N;
const int RAND_VALUE=1;
mult_mod_seg_tree(int n){N=n, seg.assign(1, node());}
mult_mod_seg_tree(){seg.assign(1, node());}
inline node merge(node par, node a, node b){
node ret;
ret.left = par.left, ret.right = par.right;
ret.val = (((ll)a.val * ((ll)b.val))) % MOD;
return ret;
}
inline void update_node(int ind, int val, int l, int r){
seg[ind].val = val;
}
inline void down(node &par, int l, int r){
/*
seg[par.left].val += par.laz * (MID-l+1);
seg[par.right].val += par.laz * (r-MID);
seg[par.left].laz = par.laz;
seg[par.right].laz = par.laz;
par.laz = 0;
*/
}
inline void create_children(int ind){
node par = seg[ind];
if(par.left==-1){
//cout<<"left\n";
par.left=seg.size(), seg.push_back(node());
}
if(par.right==-1) par.right=seg.size(), seg.push_back(node());
seg[ind] = par;
}
void build(vector<T>& arr, int l=0, int r=N-1, int ind=0){
if(l==r) seg[ind] = node(arr[l]);
else{
create_children(ind);
build(arr,l,MID,seg[ind].left);
build(arr,MID+1,r,seg[ind].right);
seg[ind] = merge(seg[ind], seg[seg[ind].left], seg[seg[ind].right]);
}
}
void update(int pos, int val, int l=0, int r=N-1, int ind=0){
if(l==r && r==pos) update_node(ind, val,l,r);
else if(pos<l || pos>r || l==r) return;
else{
create_children(ind);
down(seg[ind],l,r);
update(pos,val,l,MID,seg[ind].left);
update(pos,val,MID+1,r,seg[ind].right);
seg[ind] = merge(seg[ind], seg[seg[ind].left], seg[seg[ind].right]);
}
}
node _query(int rl, int rr, int l=0, int r=N-1, int ind=0){
if(rl<=l && r<=rr) return seg[ind];
else if(rl>r || l>rr) return RAND_VALUE;
else{
create_children(ind);
down(seg[ind],l,r);
return merge(seg[ind], _query(rl, rr, l, MID, seg[ind].left), _query(rl,rr,MID+1,r,seg[ind].right));
}
}
T query(int l, int r){
return _query(l,r).val%MOD;
}
};
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, x[pos]);
xsegm.update(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;
}
컴파일 시 표준 에러 (stderr) 메시지
horses.cpp: In function 'void time_end()':
horses.cpp:264:7: warning: unused variable 'endt' [-Wunused-variable]
264 | auto endt = clock();
| ^~~~
horses.cpp: In function 'int get_ans()':
horses.cpp:310:50: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
310 | c= ((ll) c * (ll) yseg.query(maxapos, next-1) ) %MOD;
| ^
horses.cpp: In instantiation of 'void mult_seg_tree<T>::create_children(int) [with T = double]':
horses.cpp:129:4: required from 'void mult_seg_tree<T>::build(std::vector<int>&, int, int, int) [with T = double]'
horses.cpp:326:15: required from here
horses.cpp:120:12: warning: conversion from 'std::vector<mult_seg_tree<double>::node, std::allocator<mult_seg_tree<double>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
120 | par.left=seg.size(), seg.push_back(node());
horses.cpp:122:30: warning: conversion from 'std::vector<mult_seg_tree<double>::node, std::allocator<mult_seg_tree<double>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
122 | if(par.right==-1) par.right=seg.size(), seg.push_back(node());
horses.cpp: In instantiation of 'void mult_mod_seg_tree<T>::create_children(int) [with T = int]':
horses.cpp:217:4: required from 'void mult_mod_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:329:15: required from here
horses.cpp:208:12: warning: conversion from 'std::vector<mult_mod_seg_tree<int>::node, std::allocator<mult_mod_seg_tree<int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
208 | par.left=seg.size(), seg.push_back(node());
horses.cpp:210:30: warning: conversion from 'std::vector<mult_mod_seg_tree<int>::node, std::allocator<mult_mod_seg_tree<int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
210 | if(par.right==-1) par.right=seg.size(), seg.push_back(node());
horses.cpp: In instantiation of 'mult_mod_seg_tree<T>::node mult_mod_seg_tree<T>::merge(mult_mod_seg_tree<T>::node, mult_mod_seg_tree<T>::node, mult_mod_seg_tree<T>::node) [with T = int]':
horses.cpp:221:15: required from 'void mult_mod_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:329:15: required from here
horses.cpp:184:41: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
184 | ret.val = (((ll)a.val * ((ll)b.val))) % MOD;
| ^
horses.cpp: In instantiation of 'void mult_seg_tree<T>::update_node(int, int, int, int) [with T = double]':
horses.cpp:138:22: required from 'void mult_seg_tree<T>::update(int, int, int, int, int) [with T = double]'
horses.cpp:350:26: required from here
horses.cpp:100:48: warning: unused parameter 'l' [-Wunused-parameter]
100 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:100:55: warning: unused parameter 'r' [-Wunused-parameter]
100 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp: In instantiation of 'void mult_seg_tree<T>::down(mult_seg_tree<T>::node&, int, int) [with T = double]':
horses.cpp:142:4: required from 'void mult_seg_tree<T>::update(int, int, int, int, int) [with T = double]'
horses.cpp:350:26: required from here
horses.cpp:104:25: warning: unused parameter 'par' [-Wunused-parameter]
104 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:104:34: warning: unused parameter 'l' [-Wunused-parameter]
104 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:104:41: warning: unused parameter 'r' [-Wunused-parameter]
104 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp: In instantiation of 'void mult_mod_seg_tree<T>::update_node(int, int, int, int) [with T = int]':
horses.cpp:226:22: required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int) [with T = int]'
horses.cpp:351:26: required from here
horses.cpp:188:48: warning: unused parameter 'l' [-Wunused-parameter]
188 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:188:55: warning: unused parameter 'r' [-Wunused-parameter]
188 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp: In instantiation of 'void mult_mod_seg_tree<T>::down(mult_mod_seg_tree<T>::node&, int, int) [with T = int]':
horses.cpp:230:4: required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int) [with T = int]'
horses.cpp:351:26: required from here
horses.cpp:192:25: warning: unused parameter 'par' [-Wunused-parameter]
192 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:192:34: warning: unused parameter 'l' [-Wunused-parameter]
192 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:192:41: warning: unused parameter 'r' [-Wunused-parameter]
192 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp: In instantiation of 'void seg_tree<T>::update_node(seg_tree<T>::node*, int, int, int) [with T = int]':
horses.cpp:51:22: required from 'void seg_tree<T>::update(int, int, int, int, int, seg_tree<T>::node*) [with T = int]'
horses.cpp:358:27: required from here
horses.cpp:34:50: warning: unused parameter 'l' [-Wunused-parameter]
34 | inline void update_node(node* ind, int val, int l, int r){
| ~~~~^
horses.cpp:34:57: warning: unused parameter 'r' [-Wunused-parameter]
34 | inline void update_node(node* ind, int val, int l, int r){
| ~~~~^| # | 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... |