d649a7e3ca 2015-03-26 kinaba: #include <iostream> d649a7e3ca 2015-03-26 kinaba: #include <sstream> d649a7e3ca 2015-03-26 kinaba: #include <iomanip> d649a7e3ca 2015-03-26 kinaba: #include <vector> d649a7e3ca 2015-03-26 kinaba: #include <string> d649a7e3ca 2015-03-26 kinaba: #include <map> d649a7e3ca 2015-03-26 kinaba: #include <set> d649a7e3ca 2015-03-26 kinaba: #include <algorithm> d649a7e3ca 2015-03-26 kinaba: #include <numeric> d649a7e3ca 2015-03-26 kinaba: #include <iterator> d649a7e3ca 2015-03-26 kinaba: #include <functional> d649a7e3ca 2015-03-26 kinaba: #include <complex> d649a7e3ca 2015-03-26 kinaba: #include <queue> d649a7e3ca 2015-03-26 kinaba: #include <stack> d649a7e3ca 2015-03-26 kinaba: #include <cmath> d649a7e3ca 2015-03-26 kinaba: #include <cassert> d649a7e3ca 2015-03-26 kinaba: #include <tuple> d649a7e3ca 2015-03-26 kinaba: using namespace std; d649a7e3ca 2015-03-26 kinaba: typedef long long LL; d649a7e3ca 2015-03-26 kinaba: typedef complex<double> CMP; d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: template<typename T> d649a7e3ca 2015-03-26 kinaba: class IdGen d649a7e3ca 2015-03-26 kinaba: { d649a7e3ca 2015-03-26 kinaba: map<T, int> v2id_; d649a7e3ca 2015-03-26 kinaba: vector<T> id2v_; d649a7e3ca 2015-03-26 kinaba: public: d649a7e3ca 2015-03-26 kinaba: int v2id(const T& v) { d649a7e3ca 2015-03-26 kinaba: if( !v2id_.count(v) ) { v2id_[v] = size(); id2v_.push_back(v); } d649a7e3ca 2015-03-26 kinaba: return v2id_[v]; d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: const T& id2v(int i) const { return id2v_[i]; } d649a7e3ca 2015-03-26 kinaba: int size() const { return id2v_.size(); } d649a7e3ca 2015-03-26 kinaba: }; d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: template<typename Vert=pair<int,int>, typename Flow=LL, int NV=2048> d649a7e3ca 2015-03-26 kinaba: class MaxFlow d649a7e3ca 2015-03-26 kinaba: { d649a7e3ca 2015-03-26 kinaba: IdGen<Vert> idgen; d649a7e3ca 2015-03-26 kinaba: vector<int> G[NV]; d649a7e3ca 2015-03-26 kinaba: Flow F[NV][NV]; d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: public: d649a7e3ca 2015-03-26 kinaba: void addEdge( Vert s_, Vert t_, Flow f ) d649a7e3ca 2015-03-26 kinaba: { d649a7e3ca 2015-03-26 kinaba: const int s = idgen.v2id(s_), t = idgen.v2id(t_); d649a7e3ca 2015-03-26 kinaba: G[s].push_back(t); d649a7e3ca 2015-03-26 kinaba: G[t].push_back(s); d649a7e3ca 2015-03-26 kinaba: F[s][t] = f; d649a7e3ca 2015-03-26 kinaba: F[t][s] = 0; d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: Flow calc( Vert s_, Vert t_ ) d649a7e3ca 2015-03-26 kinaba: { d649a7e3ca 2015-03-26 kinaba: const int S = idgen.v2id(s_), D = idgen.v2id(t_); d649a7e3ca 2015-03-26 kinaba: for( Flow total=0 ;; ) { d649a7e3ca 2015-03-26 kinaba: // Do BFS and compute the level for each node. d649a7e3ca 2015-03-26 kinaba: int LV[NV] = {0}; d649a7e3ca 2015-03-26 kinaba: vector<int> Q(1, S); d649a7e3ca 2015-03-26 kinaba: for(int lv=1; !Q.empty(); ++lv) { d649a7e3ca 2015-03-26 kinaba: vector<int> Q2; d649a7e3ca 2015-03-26 kinaba: for(size_t i=0; i!=Q.size(); ++i) { d649a7e3ca 2015-03-26 kinaba: const vector<int>& ne = G[Q[i]]; d649a7e3ca 2015-03-26 kinaba: for(size_t j=0; j!=ne.size(); ++j) d649a7e3ca 2015-03-26 kinaba: if( F[Q[i]][ne[j]] && !LV[ne[j]] && ne[j]!=S ) d649a7e3ca 2015-03-26 kinaba: LV[ne[j]]=lv, Q2.push_back(ne[j]); d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: Q.swap(Q2); d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: // Destination is now unreachable. Done. d649a7e3ca 2015-03-26 kinaba: if( !LV[D] ) d649a7e3ca 2015-03-26 kinaba: return total; d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: // Iterating DFS. d649a7e3ca 2015-03-26 kinaba: bool blocked[NV] = {}; d649a7e3ca 2015-03-26 kinaba: total += dinic_dfs( S, D, LV, 0x7fffffff, blocked ); d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: private: d649a7e3ca 2015-03-26 kinaba: Flow dinic_dfs( int v, int D, int LV[], Flow flow_in, bool blocked[] ) d649a7e3ca 2015-03-26 kinaba: { d649a7e3ca 2015-03-26 kinaba: Flow flow_out = 0; d649a7e3ca 2015-03-26 kinaba: for(size_t i=0; i!=G[v].size(); ++i) { d649a7e3ca 2015-03-26 kinaba: int u = G[v][i]; d649a7e3ca 2015-03-26 kinaba: if( LV[v]+1==LV[u] && F[v][u] ) { d649a7e3ca 2015-03-26 kinaba: Flow f = min(flow_in-flow_out, F[v][u]); d649a7e3ca 2015-03-26 kinaba: if( u==D || !blocked[u] && (f=dinic_dfs(u,D,LV,f,blocked))>0 ) { d649a7e3ca 2015-03-26 kinaba: F[v][u] -= f; d649a7e3ca 2015-03-26 kinaba: F[u][v] += f; d649a7e3ca 2015-03-26 kinaba: flow_out += f; d649a7e3ca 2015-03-26 kinaba: if( flow_in == flow_out ) return flow_out; d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: blocked[v] = (flow_out==0); d649a7e3ca 2015-03-26 kinaba: return flow_out; d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: }; d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: class Singing { public: d649a7e3ca 2015-03-26 kinaba: int solve(int N, int low, int high, vector <int> pitch) d649a7e3ca 2015-03-26 kinaba: { d649a7e3ca 2015-03-26 kinaba: map<pair<int,int>, int> edge; d649a7e3ca 2015-03-26 kinaba: for(int i=0; i+1<pitch.size(); ++i) { d649a7e3ca 2015-03-26 kinaba: int p0 = min(pitch[i], pitch[i+1]); d649a7e3ca 2015-03-26 kinaba: int p1 = max(pitch[i], pitch[i+1]); d649a7e3ca 2015-03-26 kinaba: if(p0 != p1) d649a7e3ca 2015-03-26 kinaba: edge[make_pair(p0,p1)] ++; d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: MaxFlow<>* mf = new MaxFlow<>; d649a7e3ca 2015-03-26 kinaba: const LL INF = 0x3fffffff; d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: enum{BOB, LEFT, RIGHT, ALICE}; d649a7e3ca 2015-03-26 kinaba: pair<int,int> Bob(BOB,0); d649a7e3ca 2015-03-26 kinaba: pair<int,int> Alice(ALICE,0); d649a7e3ca 2015-03-26 kinaba: for(int v=1; v<=N; ++v) { d649a7e3ca 2015-03-26 kinaba: if(v>high) d649a7e3ca 2015-03-26 kinaba: mf->addEdge(Bob, make_pair(LEFT,v), INF); d649a7e3ca 2015-03-26 kinaba: mf->addEdge(make_pair(LEFT,v), make_pair(RIGHT,v), INF); d649a7e3ca 2015-03-26 kinaba: if(v<low) d649a7e3ca 2015-03-26 kinaba: mf->addEdge(make_pair(RIGHT,v), Alice, INF); d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: for(auto e: edge) { d649a7e3ca 2015-03-26 kinaba: int v = e.first.first; d649a7e3ca 2015-03-26 kinaba: int u = e.first.second; d649a7e3ca 2015-03-26 kinaba: int c = e.second; d649a7e3ca 2015-03-26 kinaba: mf->addEdge(make_pair(RIGHT,v), make_pair(LEFT,u), c); d649a7e3ca 2015-03-26 kinaba: mf->addEdge(make_pair(RIGHT,u), make_pair(LEFT,v), c); d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: LL ans = mf->calc(Bob, Alice); d649a7e3ca 2015-03-26 kinaba: delete mf; d649a7e3ca 2015-03-26 kinaba: return int(ans); d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: }; d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: // BEGIN CUT HERE d649a7e3ca 2015-03-26 kinaba: #include <ctime> d649a7e3ca 2015-03-26 kinaba: double start_time; string timer() d649a7e3ca 2015-03-26 kinaba: { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } d649a7e3ca 2015-03-26 kinaba: template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) d649a7e3ca 2015-03-26 kinaba: { os << "{ "; d649a7e3ca 2015-03-26 kinaba: for(typename vector<T>::const_iterator it=v.begin(); it!=v.end(); ++it) d649a7e3ca 2015-03-26 kinaba: os << '\"' << *it << '\"' << (it+1==v.end() ? "" : ", "); os << " }"; return os; } d649a7e3ca 2015-03-26 kinaba: void verify_case(const int& Expected, const int& Received) { d649a7e3ca 2015-03-26 kinaba: bool ok = (Expected == Received); d649a7e3ca 2015-03-26 kinaba: if(ok) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; d649a7e3ca 2015-03-26 kinaba: cerr << "\to: \"" << Expected << '\"' << endl << "\tx: \"" << Received << '\"' << endl; } } d649a7e3ca 2015-03-26 kinaba: #define CASE(N) {cerr << "Test Case #" << N << "..." << flush; start_time=clock(); d649a7e3ca 2015-03-26 kinaba: #define END verify_case(_, Singing().solve(N, low, high, pitch));} d649a7e3ca 2015-03-26 kinaba: int main(){ d649a7e3ca 2015-03-26 kinaba: d649a7e3ca 2015-03-26 kinaba: CASE(0) d649a7e3ca 2015-03-26 kinaba: int N = 3; d649a7e3ca 2015-03-26 kinaba: int low = 2; d649a7e3ca 2015-03-26 kinaba: int high = 2; d649a7e3ca 2015-03-26 kinaba: int pitch_[] = {1,2,3,2,1,2}; d649a7e3ca 2015-03-26 kinaba: vector <int> pitch(pitch_, pitch_+sizeof(pitch_)/sizeof(*pitch_)); d649a7e3ca 2015-03-26 kinaba: int _ = 2; d649a7e3ca 2015-03-26 kinaba: END d649a7e3ca 2015-03-26 kinaba: CASE(1) d649a7e3ca 2015-03-26 kinaba: int N = 10; d649a7e3ca 2015-03-26 kinaba: int low = 3; d649a7e3ca 2015-03-26 kinaba: int high = 7; d649a7e3ca 2015-03-26 kinaba: int pitch_[] = {4,4,5,5,6,5,3,6}; d649a7e3ca 2015-03-26 kinaba: vector <int> pitch(pitch_, pitch_+sizeof(pitch_)/sizeof(*pitch_)); d649a7e3ca 2015-03-26 kinaba: int _ = 0; d649a7e3ca 2015-03-26 kinaba: END d649a7e3ca 2015-03-26 kinaba: CASE(2) d649a7e3ca 2015-03-26 kinaba: int N = 6; d649a7e3ca 2015-03-26 kinaba: int low = 2; d649a7e3ca 2015-03-26 kinaba: int high = 5; d649a7e3ca 2015-03-26 kinaba: int pitch_[] = {5,3,1,6,4,2}; d649a7e3ca 2015-03-26 kinaba: vector <int> pitch(pitch_, pitch_+sizeof(pitch_)/sizeof(*pitch_)); d649a7e3ca 2015-03-26 kinaba: int _ = 1; d649a7e3ca 2015-03-26 kinaba: END d649a7e3ca 2015-03-26 kinaba: CASE(3) d649a7e3ca 2015-03-26 kinaba: int N = 10; d649a7e3ca 2015-03-26 kinaba: int low = 4; d649a7e3ca 2015-03-26 kinaba: int high = 5; d649a7e3ca 2015-03-26 kinaba: int pitch_[] = {1,4,3,5,2,5,7,5,9}; d649a7e3ca 2015-03-26 kinaba: vector <int> pitch(pitch_, pitch_+sizeof(pitch_)/sizeof(*pitch_)); d649a7e3ca 2015-03-26 kinaba: int _ = 3; d649a7e3ca 2015-03-26 kinaba: END d649a7e3ca 2015-03-26 kinaba: CASE(4) d649a7e3ca 2015-03-26 kinaba: int N = 100; d649a7e3ca 2015-03-26 kinaba: int low = 20; d649a7e3ca 2015-03-26 kinaba: int high = 80; d649a7e3ca 2015-03-26 kinaba: int pitch_[] = {2,27,3,53,53,52,52,60,85,89,100,53,60,2,3,53,100,89,40,42,2,53,2,85}; d649a7e3ca 2015-03-26 kinaba: vector <int> pitch(pitch_, pitch_+sizeof(pitch_)/sizeof(*pitch_)); d649a7e3ca 2015-03-26 kinaba: int _ = 5; d649a7e3ca 2015-03-26 kinaba: END d649a7e3ca 2015-03-26 kinaba: /* d649a7e3ca 2015-03-26 kinaba: CASE(5) d649a7e3ca 2015-03-26 kinaba: int N = ; d649a7e3ca 2015-03-26 kinaba: int low = ; d649a7e3ca 2015-03-26 kinaba: int high = ; d649a7e3ca 2015-03-26 kinaba: int pitch_[] = ; d649a7e3ca 2015-03-26 kinaba: vector <int> pitch(pitch_, pitch_+sizeof(pitch_)/sizeof(*pitch_)); d649a7e3ca 2015-03-26 kinaba: int _ = ; d649a7e3ca 2015-03-26 kinaba: END d649a7e3ca 2015-03-26 kinaba: CASE(6) d649a7e3ca 2015-03-26 kinaba: int N = ; d649a7e3ca 2015-03-26 kinaba: int low = ; d649a7e3ca 2015-03-26 kinaba: int high = ; d649a7e3ca 2015-03-26 kinaba: int pitch_[] = ; d649a7e3ca 2015-03-26 kinaba: vector <int> pitch(pitch_, pitch_+sizeof(pitch_)/sizeof(*pitch_)); d649a7e3ca 2015-03-26 kinaba: int _ = ; d649a7e3ca 2015-03-26 kinaba: END d649a7e3ca 2015-03-26 kinaba: */ d649a7e3ca 2015-03-26 kinaba: } d649a7e3ca 2015-03-26 kinaba: // END CUT HERE