Submission #286640

#TimeUsernameProblemLanguageResultExecution timeMemory
286640user202729Wiring (IOI17_wiring)C++17
100 / 100
63 ms8696 KiB
// moreflags=grader.cpp // // 13 // :( #include "wiring.h" #include<vector> #if not LOCAL #define NDEBUG #endif #include<cassert> #include<climits> #include<cstdint> #include<algorithm> struct Point{ bool red; int pos; bool operator<(Point other) const{return pos<other.pos;} }; template<bool type> struct Iterator { using B=std::iterator<std::forward_iterator_tag, Point>; #define F(N) using N=typename B::N F(iterator_category); F(value_type); F(difference_type); F(pointer); F(reference); #undef F std::vector<int>::iterator iterator; #define F(op) bool operator op (Iterator other) const{return iterator op other.iterator;} //F(<) F(>) F(==) F(!=) #undef F Iterator& operator++(){ ++iterator; return *this; } Point operator*() const{return {type, *iterator};} }; // rust is nicer than this... long long min_total_length(std::vector<int> red, std::vector<int> blue) { std::vector<Point> points; points.reserve(red.size()+blue.size()); std::merge( Iterator<true>{red.begin()}, Iterator<true>{red.end()}, Iterator<false>{blue.begin()}, Iterator<false>{blue.end()}, std::back_inserter(points)); assert(points.size()==red.size()+blue.size()); std::vector<int64_t> sumSuffix(points.size()+1); for(auto [last, index]=std::pair((int64_t)0, points.size()); index--;){ sumSuffix[index]=last+=points[index].pos; } // std::partial_sum std::vector<int64_t> result(points.size()+1, INT64_MAX); result[0]=0; auto const groupEnd=[&](int index){ int result=index; while(result<(int)points.size() and points[result].red==points[index].red) ++result; return result; }; int last=-1, next=groupEnd(0), next2=groupEnd(next); for(int index=0; index<(int)points.size(); ++index){ if(index==next){ last=index-1; next=next2; next2=groupEnd(next2); } auto const curResult=result[index]; if(last>=0) result[index+1]=std::min(result[index+1], curResult+points[index].pos-points[last].pos); if(next<(int)points.size()) result[index+1]=std::min(result[index+1], curResult+points[next].pos-points[index].pos); if(auto const block=next-index; next2-next>=block) result[next+block]=std::min(result[next+block], curResult +(sumSuffix[next]-sumSuffix[next+block]) -(sumSuffix[index]-sumSuffix[next]) ); } return result[points.size()]; }
#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...