이 제출은 이전 버전의 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 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 = (a.val * 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;
}
};
#define ll long long
typedef vector<ll> vi;
vi x,y;
vector<long double> a;
set<int> xx;
seg_tree<ll> yseg;
mult_seg_tree<long double> xsegd;
mult_mod_seg_tree<ll> xsegm;
#define FOA(v,qq) for(auto v : qq)
int get_ans(){
auto it = xx.end();
it--;
it--;
int cnt=0;
long double maxa=0;
int maxapos=-1, next=-1;
//FOA(v,xx) cout<<v<<" ";
//cout<<endl;
auto itt = xx.begin();
advance(itt, max(len(xx)-38, 0));
int f = *itt;
while(cnt<35){
auto it2 = it;
it2++;
//cout<<*it<<" "<<*it2<<endl;
long 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--;
}
ll c = xsegm.query(0, maxapos);
//if(c==0) cout<<"Hmmmm\n";
c*=yseg.query(maxapos, next-1);
//if(c==0) cout<<"hm"<<maxapos<<" "<<next-1<<"\n";
c%=MOD;
//cout<<endl;
return c;
}
vector<long 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:23:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
23 | static inline int N;
| ^~~~~~
horses.cpp:111:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
111 | static inline int N;
| ^~~~~~
horses.cpp:199:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
199 | static inline int N;
| ^~~~~~
horses.cpp: In function 'int get_ans()':
horses.cpp:325:9: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
325 | return c;
| ^
horses.cpp: In function 'int updateX(int, int)':
horses.cpp:363:32: warning: conversion from '__gnu_cxx::__alloc_traits<std::allocator<long double>, long double>::value_type' {aka 'long double'} to 'int' may change value [-Wfloat-conversion]
363 | xsegd.update(pos, pos, dx[pos]);
| ^
horses.cpp:364:31: warning: conversion from '__gnu_cxx::__alloc_traits<std::allocator<long long int>, long long int>::value_type' {aka 'long long int'} to 'int' may change value [-Wconversion]
364 | xsegm.update(pos, pos, x[pos]);
| ^
horses.cpp: In instantiation of 'void seg_tree<T>::create_children(int) [with T = long long int]':
horses.cpp:64:4: required from 'void seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = long long int]'
horses.cpp:339:14: required from here
horses.cpp:55:12: warning: conversion from 'std::vector<seg_tree<long long int>::node, std::allocator<seg_tree<long long int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
55 | par.left=seg.size(), seg.push_back(node());
horses.cpp:57:30: warning: conversion from 'std::vector<seg_tree<long long int>::node, std::allocator<seg_tree<long long int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
57 | 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 = long double]':
horses.cpp:152:4: required from 'void mult_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = long double]'
horses.cpp:342:16: required from here
horses.cpp:143:12: warning: conversion from 'std::vector<mult_seg_tree<long double>::node, std::allocator<mult_seg_tree<long double>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
143 | par.left=seg.size(), seg.push_back(node());
horses.cpp:145:30: warning: conversion from 'std::vector<mult_seg_tree<long double>::node, std::allocator<mult_seg_tree<long double>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
145 | 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 = long long int]':
horses.cpp:242:4: required from 'void mult_mod_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = long long int]'
horses.cpp:345:15: required from here
horses.cpp:233:12: warning: conversion from 'std::vector<mult_mod_seg_tree<long long int>::node, std::allocator<mult_mod_seg_tree<long long int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
233 | par.left=seg.size(), seg.push_back(node());
horses.cpp:235:30: warning: conversion from 'std::vector<mult_mod_seg_tree<long long int>::node, std::allocator<mult_mod_seg_tree<long long int>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
235 | if(par.right==-1) par.right=seg.size(), seg.push_back(node());
horses.cpp: In instantiation of 'void mult_seg_tree<T>::update_node(int, int, int, int) [with T = long double]':
horses.cpp:161:22: required from 'void mult_seg_tree<T>::update(int, int, int, int, int, int) [with T = long double]'
horses.cpp:363:32: required from here
horses.cpp:123:48: warning: unused parameter 'l' [-Wunused-parameter]
123 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:123:55: warning: unused parameter 'r' [-Wunused-parameter]
123 | 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 = long double]':
horses.cpp:165:4: required from 'void mult_seg_tree<T>::update(int, int, int, int, int, int) [with T = long double]'
horses.cpp:363:32: required from here
horses.cpp:127:25: warning: unused parameter 'par' [-Wunused-parameter]
127 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:127:34: warning: unused parameter 'l' [-Wunused-parameter]
127 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:127:41: warning: unused parameter 'r' [-Wunused-parameter]
127 | 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 = long long int]':
horses.cpp:251:22: required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int, int) [with T = long long int]'
horses.cpp:364:31: required from here
horses.cpp:213:48: warning: unused parameter 'l' [-Wunused-parameter]
213 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:213:55: warning: unused parameter 'r' [-Wunused-parameter]
213 | 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 = long long int]':
horses.cpp:255:4: required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int, int) [with T = long long int]'
horses.cpp:364:31: required from here
horses.cpp:217:25: warning: unused parameter 'par' [-Wunused-parameter]
217 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:217:34: warning: unused parameter 'l' [-Wunused-parameter]
217 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:217:41: warning: unused parameter 'r' [-Wunused-parameter]
217 | 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 = long long int]':
horses.cpp:73:22: required from 'void seg_tree<T>::update(int, int, int, int, int, int) [with T = long long int]'
horses.cpp:369:27: required from here
horses.cpp:35:48: warning: unused parameter 'l' [-Wunused-parameter]
35 | inline void update_node(int ind, int val, int l, int r){
| ~~~~^
horses.cpp:35:55: warning: unused parameter 'r' [-Wunused-parameter]
35 | 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 = long long int]':
horses.cpp:77:4: required from 'void seg_tree<T>::update(int, int, int, int, int, int) [with T = long long int]'
horses.cpp:369:27: required from here
horses.cpp:39:25: warning: unused parameter 'par' [-Wunused-parameter]
39 | inline void down(node &par, int l, int r){
| ~~~~~~^~~
horses.cpp:39:34: warning: unused parameter 'l' [-Wunused-parameter]
39 | inline void down(node &par, int l, int r){
| ~~~~^
horses.cpp:39:41: warning: unused parameter 'r' [-Wunused-parameter]
39 | 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... |