Submission #290572

#TimeUsernameProblemLanguageResultExecution timeMemory
290572user202729Seats (IOI18_seats)C++17
11 / 100
4097 ms53880 KiB
// moreflags=grader.cpp // 8 // inefficient version #include "seats.h" #include<vector> #include<algorithm> #if not LOCAL #define NDEBUG #endif #include<cassert> struct MyData{ static int constexpr blockSize=100; struct Pos{int row, col;}; struct Rectangle{Pos minimum, maximum; Rectangle& operator+=(Rectangle other){ minimum.row=std::min(minimum.row, other.minimum.row); minimum.col=std::min(minimum.col, other.minimum.col); maximum.row=std::max(maximum.row, other.maximum.row); maximum.col=std::max(maximum.col, other.maximum.col); return *this; } Rectangle operator+(Rectangle other) const{return other+=*this;} int area() const{ assert(maximum.row>minimum.row); assert(maximum.col>minimum.col); return (maximum.row-minimum.row)*(maximum.col-minimum.col); } static Rectangle from(Pos it){return Rectangle{it, {it.row+1, it.col+1}};} }; struct Cover{Rectangle bound; int missing; Cover operator+(Cover other) const{ auto const resultBound=bound+other.bound; auto const resultMissing=resultBound.area()-( bound.area()-missing+other.bound.area()-other.missing ); assert(resultMissing>=0); return {resultBound, resultMissing}; } }; struct Block{ std::vector<Cover> cover; std::array<Pos, blockSize> items; int number; void build(){ // recompute cover. O(number) assert(number<=blockSize); assert(number!=0); cover.clear(); cover.push_back({Rectangle::from(items[0]), 0}); for(int index=1; index<number; ++index){ auto& [prevBound, prevMissing]=cover.back(); auto const next=Rectangle::from(items[index])+prevBound; auto const diff=next.area()-prevBound.area(); assert(diff>=0); if(diff==0){ assert(prevMissing>0); --prevMissing; }else{ cover.push_back({next, prevMissing+diff-1}); } } } void setWithoutBuild(int index, Pos pos){ assert(index<number); items[index]=pos; } std::pair<int, Cover> get(Cover previous)const{ // inefficient int result=0; for(auto it: cover) if((previous+it).missing==0) ++result; return {result, previous+cover.back()}; } }; int number; std::vector<Block> data; MyData(){} MyData(int const number, std::vector<int> const& R, std::vector<int> const& C): number(number), data((number-1)/blockSize+1) { assert(number!=0); for(auto& it: data) it.number=blockSize; data.back().number-=(int)data.size()*blockSize-number; assert((int)R.size()==number); assert((int)C.size()==number); for(int block=0; block<(int)data.size(); ++block) for(int index=0; index<data[block].number; ++index) data[block].items[index]={R[block*blockSize+index], C[block*blockSize+index]}; for(auto& it: data) it.build(); } int getResult(){ Cover current{Rectangle::from(data[0].items[0]), 1}; int result{}; for(auto const& it: data){ auto [count, next]=it.get(current); result+=count; current=next; } assert(current.missing==0); assert(result>0); return result; } Pos get(int index) const{ assert(0<=index); assert(index<number); return data[index/blockSize].items[index%blockSize]; } int swap(int first, int sec){ auto const x=get(first), y=get(sec); data[first/blockSize].setWithoutBuild(first%blockSize, y); data[sec/blockSize].setWithoutBuild(sec%blockSize, x); data[first/blockSize].build(); if(first/blockSize!=sec/blockSize) data[sec/blockSize].build(); return getResult(); } } myData; void give_initial_chart(int H, int W, std::vector<int> R, std::vector<int> C) { myData=MyData{H*W, R, C}; } int swap_seats(int a, int b) { return myData.swap(a, b); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...