제출 #297606

#제출 시각아이디문제언어결과실행 시간메모리
297606cfalasHorses (IOI15_horses)C++14
17 / 100
1564 ms80512 KiB
#pragma GCC target("avx2") #pragma GCC optimization("O3") #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<float> a; set<int> xx; seg_tree<int> yseg; mult_seg_tree<float> 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; float 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; float c = xsegd.query(f, *it); assert(c>0); //cout<<c<<" "; c*=(float)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<float> 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:2: warning: ignoring #pragma GCC optimization [-Wunknown-pragmas]
    2 | #pragma GCC optimization("O3")
      | 
horses.cpp:26:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
   26 |  static inline int N;
      |         ^~~~~~
horses.cpp:114:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
  114 |  static inline int N;
      |         ^~~~~~
horses.cpp:202:9: warning: inline variables are only available with '-std=c++17' or '-std=gnu++17'
  202 |  static inline int N;
      |         ^~~~~~
horses.cpp: In function 'int get_ans()':
horses.cpp:324:50: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  324 |  c= ((ll) c * (ll) yseg.query(maxapos, next-1) ) %MOD;
      |                                                  ^
horses.cpp: In function 'int init(int, int*, int*)':
horses.cpp:337:22: warning: conversion from 'int' to '__gnu_cxx::__alloc_traits<std::allocator<float>, float>::value_type' {aka 'float'} may change value [-Wconversion]
  337 |  FOR(i,N) dx[i] = X[i];
      |                   ~~~^
horses.cpp: In function 'int updateX(int, int)':
horses.cpp:364:12: warning: conversion from 'int' to '__gnu_cxx::__alloc_traits<std::allocator<float>, float>::value_type' {aka 'float'} may change value [-Wconversion]
  364 |  dx[pos] = val;
      |            ^~~
horses.cpp:365:32: warning: conversion from '__gnu_cxx::__alloc_traits<std::allocator<float>, float>::value_type' {aka 'float'} to 'int' may change value [-Wfloat-conversion]
  365 |  xsegd.update(pos, pos, dx[pos]);
      |                                ^
horses.cpp: In instantiation of 'mult_seg_tree<T>::node mult_seg_tree<T>::_query(int, int, int, int, int) [with T = float]':
horses.cpp:186:10:   required from 'T mult_seg_tree<T>::query(int, int) [with T = float]'
horses.cpp:307:31:   required from here
horses.cpp:177:32: warning: conversion from 'int' to 'float' may change value [-Wconversion]
  177 |   else if(rl>r || l>rr) return RAND_VALUE;
      |                                ^~~~~~~~~~
horses.cpp: In instantiation of 'void seg_tree<T>::create_children(int) [with T = int]':
horses.cpp:67:4:   required from 'void seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:341:14:   required from here
horses.cpp:58: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]
   58 |    par.left=seg.size(), seg.push_back(node());
horses.cpp:60: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]
   60 |   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 = float]':
horses.cpp:155:4:   required from 'void mult_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = float]'
horses.cpp:344:16:   required from here
horses.cpp:146:12: warning: conversion from 'std::vector<mult_seg_tree<float>::node, std::allocator<mult_seg_tree<float>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
  146 |    par.left=seg.size(), seg.push_back(node());
horses.cpp:148:30: warning: conversion from 'std::vector<mult_seg_tree<float>::node, std::allocator<mult_seg_tree<float>::node> >::size_type' {aka 'long unsigned int'} to 'int' may change value [-Wconversion]
  148 |   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:245:4:   required from 'void mult_mod_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:347:15:   required from here
horses.cpp:236: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]
  236 |    par.left=seg.size(), seg.push_back(node());
horses.cpp:238: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]
  238 |   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:249:15:   required from 'void mult_mod_seg_tree<T>::build(std::vector<_Tp>&, int, int, int) [with T = int]'
horses.cpp:347:15:   required from here
horses.cpp:212:41: warning: conversion from 'long long int' to 'int' may change value [-Wconversion]
  212 |   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 = float]':
horses.cpp:164:22:   required from 'void mult_seg_tree<T>::update(int, int, int, int, int, int) [with T = float]'
horses.cpp:365:32:   required from here
horses.cpp:127:18: warning: conversion from 'int' to 'float' may change value [-Wconversion]
  127 |   seg[ind].val = val;
      |                  ^~~
horses.cpp:126:48: warning: unused parameter 'l' [-Wunused-parameter]
  126 |  inline void update_node(int ind, int val, int l, int r){
      |                                            ~~~~^
horses.cpp:126:55: warning: unused parameter 'r' [-Wunused-parameter]
  126 |  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 = float]':
horses.cpp:168:4:   required from 'void mult_seg_tree<T>::update(int, int, int, int, int, int) [with T = float]'
horses.cpp:365:32:   required from here
horses.cpp:130:25: warning: unused parameter 'par' [-Wunused-parameter]
  130 |  inline void down(node &par, int l, int r){
      |                   ~~~~~~^~~
horses.cpp:130:34: warning: unused parameter 'l' [-Wunused-parameter]
  130 |  inline void down(node &par, int l, int r){
      |                              ~~~~^
horses.cpp:130:41: warning: unused parameter 'r' [-Wunused-parameter]
  130 |  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:254:22:   required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:366:31:   required from here
horses.cpp:216:48: warning: unused parameter 'l' [-Wunused-parameter]
  216 |  inline void update_node(int ind, int val, int l, int r){
      |                                            ~~~~^
horses.cpp:216:55: warning: unused parameter 'r' [-Wunused-parameter]
  216 |  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:258:4:   required from 'void mult_mod_seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:366:31:   required from here
horses.cpp:220:25: warning: unused parameter 'par' [-Wunused-parameter]
  220 |  inline void down(node &par, int l, int r){
      |                   ~~~~~~^~~
horses.cpp:220:34: warning: unused parameter 'l' [-Wunused-parameter]
  220 |  inline void down(node &par, int l, int r){
      |                              ~~~~^
horses.cpp:220:41: warning: unused parameter 'r' [-Wunused-parameter]
  220 |  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:76:22:   required from 'void seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:371:27:   required from here
horses.cpp:38:48: warning: unused parameter 'l' [-Wunused-parameter]
   38 |  inline void update_node(int ind, int val, int l, int r){
      |                                            ~~~~^
horses.cpp:38:55: warning: unused parameter 'r' [-Wunused-parameter]
   38 |  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:80:4:   required from 'void seg_tree<T>::update(int, int, int, int, int, int) [with T = int]'
horses.cpp:371:27:   required from here
horses.cpp:42:25: warning: unused parameter 'par' [-Wunused-parameter]
   42 |  inline void down(node &par, int l, int r){
      |                   ~~~~~~^~~
horses.cpp:42:34: warning: unused parameter 'l' [-Wunused-parameter]
   42 |  inline void down(node &par, int l, int r){
      |                              ~~~~^
horses.cpp:42:41: warning: unused parameter 'r' [-Wunused-parameter]
   42 |  inline void down(node &par, int l, int r){
      |                                     ~~~~^
#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...