이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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;
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;
seg_tree(int n){N=n, seg.assign(1, node());}
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 = max(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<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 rl, int rr, int val, int l=0, int r=N-1, int ind=0){
if(rl<=l && r<=rr) update_node(ind, val,l,r);
else if(rr<l || r<rl) return;
else{
create_children(ind);
down(seg[ind],l,r);
update(rl,rr,val,l,MID,seg[ind].left);
update(rl,rr,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_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<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 rl, int rr, int val, int l=0, int r=N-1, int ind=0){
if(rl<=l && r<=rr) update_node(ind, val,l,r);
else if(rr<l || r<rl) return;
else{
create_children(ind);
down(seg[ind],l,r);
update(rl,rr,val,l,MID,seg[ind].left);
update(rl,rr,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;
a.val%=MOD;
b.val%=MOD;
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 rl, int rr, int val, int l=0, int r=N-1, int ind=0){
if(rl<=l && r<=rr) update_node(ind, val,l,r);
else if(rr<l || r<rl) return;
else{
create_children(ind);
down(seg[ind],l,r);
update(rl,rr,val,l,MID,seg[ind].left);
update(rl,rr,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;
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;
//FOA(v,xx) cout<<v<<" ";
//cout<<endl;
auto itt = xx.begin();
advance(itt, max(len(xx)-31, 0));
int f = *itt;
while(cnt<30){
auto it2 = it;
it2++;
//cout<<*it<<" "<<*it2<<endl;
double c = xsegd.query(f, *it);
assert(c>0);
//cout<<c<<" ";
c*=(double)yseg.query(*it, *it2-1);
//cout<<c<<endl;
if(c>maxa){
maxa = c;
maxapos = *it;
next = *it2;
}
cnt++;
if(it==xx.begin()) break;
it--;
}
int c = xsegm.query(0, maxapos);
//if(c==0) cout<<"Hmmmm\n";
c= ((ll) c * (ll) yseg.query(maxapos, next-1) ) %MOD;
//if(c==0) cout<<"hm"<<maxapos<<" "<<next-1<<"\n";
//cout<<endl;
return c;
}
vector<double> dx;
int init(int N, int X[], int Y[]) {
dx.resize(N);
x.resize(N);
y.resize(N);
FOR(i,N) x[i] = X[i];
FOR(i,N) dx[i] = X[i];
FOR(i,N) y[i] = Y[i];
yseg.N = N;
yseg.build(y);
xsegd.N = N;
xsegd.build(dx);
xsegm.N = N;
xsegm.build(x);
FOR(i,N){
if(x[i]>1) xx.insert(i);
}
xx.insert(N);
xx.insert(0);
return get_ans();
}
int updateX(int pos, int val) {
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;
dx[pos] = val;
xsegd.update(pos, pos, dx[pos]);
xsegm.update(pos, pos, x[pos]);
return get_ans();
}
int updateY(int pos, int val) {
yseg.update(pos, pos, val);
y[pos] = val;
return get_ans();
}
컴파일 시 표준 에러 (stderr) 메시지
horses.cpp:24:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
24 | static inline int N;
| ^~~~~~
horses.cpp:112:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
112 | static inline int N;
| ^~~~~~
horses.cpp:200:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
200 | static inline int N;
| ^~~~~~
horses.cpp: In function 'int get_ans()':
horses.cpp:322:50: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
322 | c= ((ll) c * (ll) yseg.query(maxapos, next-1) ) %MOD;
| ^
horses.cpp: In function 'int updateX(int, int)':
horses.cpp:363:32: warning: conversion from '__gnu_cxx::__alloc_traits<std::allocator<double>, double>::value_type' {aka 'double'} to 'int' may change value [-Wfloat-conversion]
363 | xsegd.update(pos, pos, dx[pos]);
| ^
horses.cpp: In instantiation of 'void seg_tree<T>::create_children(int) [with T = int]':
horses.cpp:65:4: required from 'void seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:339:14: required from here
horses.cpp:56:12: warning: conversion from 'std::vector<seg_tree<int>::node, std::allocator<seg_tree<int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
56 | par.left=seg.size(), seg.push_back(node());
horses.cpp:58:30: warning: conversion from 'std::vector<seg_tree<int>::node, std::allocator<seg_tree<int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
58 | if(par.right==-1) par.right=seg.size(), seg.push_back(node());
horses.cpp: In instantiation of 'void mult_seg_tree<T>::create_children(int) [with T = double]':
horses.cpp:153:4: required from 'void mult_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = double]'
horses.cpp:342:16: required from here
horses.cpp:144: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]
144 | par.left=seg.size(), seg.push_back(node());
horses.cpp:146: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]
146 | 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:243:4: required from 'void mult_mod_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:345:15: required from here
horses.cpp:234: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]
234 | par.left=seg.size(), seg.push_back(node());
horses.cpp:236: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]
236 | 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:247:15: required from 'void mult_mod_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:345:15: required from here
horses.cpp:210:41: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
210 | 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:162:22: required from 'void mult_seg_tree<T>::update(int, int, int, int, int, int) [with T = double]'
horses.cpp:363:32: required from here
horses.cpp:124:48: warning: unused parameter 'l' [-Wunused-parameter]
124 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:124:55: warning: unused parameter 'r' [-Wunused-parameter]
124 | 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:166:4: required from 'void mult_seg_tree<T>::update(int, int, int, int, int, int) [with T = double]'
horses.cpp:363:32: required from here
horses.cpp:128:25: warning: unused parameter 'par' [-Wunused-parameter]
128 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:128:34: warning: unused parameter 'l' [-Wunused-parameter]
128 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:128:41: warning: unused parameter 'r' [-Wunused-parameter]
128 | 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:252:22: required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:364:31: required from here
horses.cpp:214:48: warning: unused parameter 'l' [-Wunused-parameter]
214 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:214:55: warning: unused parameter 'r' [-Wunused-parameter]
214 | 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:256:4: required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:364:31: required from here
horses.cpp:218:25: warning: unused parameter 'par' [-Wunused-parameter]
218 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:218:34: warning: unused parameter 'l' [-Wunused-parameter]
218 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:218:41: warning: unused parameter 'r' [-Wunused-parameter]
218 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp: In instantiation of 'void seg_tree<T>::update_node(int, int, int, int) [with T = int]':
horses.cpp:74:22: required from 'void seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:369:27: required from here
horses.cpp:36:48: warning: unused parameter 'l' [-Wunused-parameter]
36 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:36:55: warning: unused parameter 'r' [-Wunused-parameter]
36 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp: In instantiation of 'void seg_tree<T>::down(seg_tree<T>::node&, int, int) [with T = int]':
horses.cpp:78:4: required from 'void seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:369:27: required from here
horses.cpp:40:25: warning: unused parameter 'par' [-Wunused-parameter]
40 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:40:34: warning: unused parameter 'l' [-Wunused-parameter]
40 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:40:41: warning: unused parameter 'r' [-Wunused-parameter]
40 | inline void down(node &par, 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... |