4fd800b3a8 2011-02-23 kinaba: #include <iostream> 4fd800b3a8 2011-02-23 kinaba: #include <sstream> 4fd800b3a8 2011-02-23 kinaba: #include <iomanip> 4fd800b3a8 2011-02-23 kinaba: #include <vector> 4fd800b3a8 2011-02-23 kinaba: #include <string> 4fd800b3a8 2011-02-23 kinaba: #include <map> 4fd800b3a8 2011-02-23 kinaba: #include <set> 4fd800b3a8 2011-02-23 kinaba: #include <algorithm> 4fd800b3a8 2011-02-23 kinaba: #include <numeric> 4fd800b3a8 2011-02-23 kinaba: #include <iterator> 4fd800b3a8 2011-02-23 kinaba: #include <complex> 4fd800b3a8 2011-02-23 kinaba: #include <queue> 4fd800b3a8 2011-02-23 kinaba: #include <stack> 4fd800b3a8 2011-02-23 kinaba: #include <cmath> 4fd800b3a8 2011-02-23 kinaba: #include <cassert> 4fd800b3a8 2011-02-23 kinaba: #include <cstring> 4fd800b3a8 2011-02-23 kinaba: #include <cstdlib> 4fd800b3a8 2011-02-23 kinaba: using namespace std; 4fd800b3a8 2011-02-23 kinaba: typedef long long LL; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template<typename T> 4fd800b3a8 2011-02-23 kinaba: struct RMQ 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: vector< vector<int> > rm; 4fd800b3a8 2011-02-23 kinaba: T* d; 4fd800b3a8 2011-02-23 kinaba: int n; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: RMQ( T* d, int n ) : d(d), n(n) { 4fd800b3a8 2011-02-23 kinaba: rm.push_back( vector<int>(n) ); 4fd800b3a8 2011-02-23 kinaba: for(int x=0; x<n; ++x) 4fd800b3a8 2011-02-23 kinaba: rm[0][x] = x; 4fd800b3a8 2011-02-23 kinaba: for(int k=1; (1<<k)<=n; ++k) { 4fd800b3a8 2011-02-23 kinaba: rm.push_back( rm[k-1] ); 4fd800b3a8 2011-02-23 kinaba: for(int x=0; x+(1<<k-1)<n; ++x) 4fd800b3a8 2011-02-23 kinaba: if( d[rm[k][x]] > d[rm[k-1][x + (1<<k-1)]] ) 4fd800b3a8 2011-02-23 kinaba: rm[k][x] = rm[k-1][x + (1<<k-1)]; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: int operator()(int L, int R) const { 4fd800b3a8 2011-02-23 kinaba: int k=0; 4fd800b3a8 2011-02-23 kinaba: for(; L+(1<<k) < R-(1<<k)+1; ++k) {} 4fd800b3a8 2011-02-23 kinaba: LL i = rm[k][L]; 4fd800b3a8 2011-02-23 kinaba: LL j = rm[k][R-(1<<k)+1]; 4fd800b3a8 2011-02-23 kinaba: return (d[i]<=d[j] ? i : j); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: vector<int> all(int L, int R) const { 4fd800b3a8 2011-02-23 kinaba: vector<int> ans; 4fd800b3a8 2011-02-23 kinaba: int minValue = d[(*this)(L, R)]; 4fd800b3a8 2011-02-23 kinaba: while( L <= R ) { 4fd800b3a8 2011-02-23 kinaba: int C = (*this)(L, R); 4fd800b3a8 2011-02-23 kinaba: if( minValue < d[C] ) 4fd800b3a8 2011-02-23 kinaba: break; 4fd800b3a8 2011-02-23 kinaba: ans.push_back(C); 4fd800b3a8 2011-02-23 kinaba: L = C+1; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: return ans; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: }; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: int B[2048][2048]; 4fd800b3a8 2011-02-23 kinaba: int U[2048][2048]; 4fd800b3a8 2011-02-23 kinaba: int D[2048][2048]; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: class PerfectRectangles 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: public: 4fd800b3a8 2011-02-23 kinaba: int numberOfRectangles(int N, int M, int X0, int A, int _B, int Y0, int C, int _D) 4fd800b3a8 2011-02-23 kinaba: { 4fd800b3a8 2011-02-23 kinaba: // input 4fd800b3a8 2011-02-23 kinaba: int x=X0%N, y=Y0%N; 4fd800b3a8 2011-02-23 kinaba: memset(B, 0, sizeof(B)); 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i<M; ++i) { 4fd800b3a8 2011-02-23 kinaba: B[x][y] = 1; 4fd800b3a8 2011-02-23 kinaba: x = (x*A+_B)%N; 4fd800b3a8 2011-02-23 kinaba: y = (y*C+_D)%N; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // up 4fd800b3a8 2011-02-23 kinaba: for(int y=0; y<N; ++y) 4fd800b3a8 2011-02-23 kinaba: for(int x=0; x<N; ++x) 4fd800b3a8 2011-02-23 kinaba: U[y][x] = (B[y][x] ? 0 : y==0 ? 1 : U[y-1][x]+1); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // down 4fd800b3a8 2011-02-23 kinaba: for(int y=N-1; y>=0; --y) 4fd800b3a8 2011-02-23 kinaba: for(int x=0; x<N; ++x) 4fd800b3a8 2011-02-23 kinaba: D[y][x] = (B[y][x] ? 0 : y==N-1 ? 1 : D[y+1][x]+1); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // solve 4fd800b3a8 2011-02-23 kinaba: int cnt = 0; 4fd800b3a8 2011-02-23 kinaba: for(int y=0; y<N; ++y) { 4fd800b3a8 2011-02-23 kinaba: RMQ<int> rmU(U[y], N); 4fd800b3a8 2011-02-23 kinaba: RMQ<int> rmD(D[y], N); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: stack< pair<int,int> > S; 4fd800b3a8 2011-02-23 kinaba: S.push( make_pair(0, N-1) ); 4fd800b3a8 2011-02-23 kinaba: while( !S.empty() ) { 4fd800b3a8 2011-02-23 kinaba: int L = S.top().first; 4fd800b3a8 2011-02-23 kinaba: int R = S.top().second; 4fd800b3a8 2011-02-23 kinaba: S.pop(); 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: int d = rmD(L,R); 4fd800b3a8 2011-02-23 kinaba: if( D[y][d] == 1 ) 4fd800b3a8 2011-02-23 kinaba: ++cnt; 4fd800b3a8 2011-02-23 kinaba: if( D[y][d] <= 1 ) { 4fd800b3a8 2011-02-23 kinaba: vector<int> m = rmU.all(L, R); 4fd800b3a8 2011-02-23 kinaba: m.push_back(R+1); 4fd800b3a8 2011-02-23 kinaba: for(int i=0; i<m.size(); L=m[i++]+1) 4fd800b3a8 2011-02-23 kinaba: if( L <= m[i]-1 ) 4fd800b3a8 2011-02-23 kinaba: S.push( make_pair(L, m[i]-1) ); 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: return cnt; 4fd800b3a8 2011-02-23 kinaba: } 4fd800b3a8 2011-02-23 kinaba: }; 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: // BEGIN CUT HERE 4fd800b3a8 2011-02-23 kinaba: #include <ctime> 4fd800b3a8 2011-02-23 kinaba: double start_time;string timer() { ostringstream os; os << " (" << int((clock()-start_time)/CLOCKS_PER_SEC*1000) << " msec)"; return os.str(); } 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 4fd800b3a8 2011-02-23 kinaba: int verify_case(const int &Expected, const int &Received) { if (Expected == Received) cerr << "PASSED" << timer() << endl; else { cerr << "FAILED" << timer() << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } return 0;} 4fd800b3a8 2011-02-23 kinaba: 4fd800b3a8 2011-02-23 kinaba: template<int N> struct Case_ { Case_(){start_time=clock();} }; 4fd800b3a8 2011-02-23 kinaba: char Test_(...); 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<0>) { 4fd800b3a8 2011-02-23 kinaba: int N = 5; 4fd800b3a8 2011-02-23 kinaba: int M = 1; 4fd800b3a8 2011-02-23 kinaba: int X0 = 2; 4fd800b3a8 2011-02-23 kinaba: int A = 0; 4fd800b3a8 2011-02-23 kinaba: int B = 0; 4fd800b3a8 2011-02-23 kinaba: int Y0 = 2; 4fd800b3a8 2011-02-23 kinaba: int C = 0; 4fd800b3a8 2011-02-23 kinaba: int D = 0; 4fd800b3a8 2011-02-23 kinaba: int RetVal = 4; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, PerfectRectangles().numberOfRectangles(N, M, X0, A, B, Y0, C, D)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<1>) { 4fd800b3a8 2011-02-23 kinaba: int N = 4; 4fd800b3a8 2011-02-23 kinaba: int M = 4; 4fd800b3a8 2011-02-23 kinaba: int X0 = 0; 4fd800b3a8 2011-02-23 kinaba: int A = 1; 4fd800b3a8 2011-02-23 kinaba: int B = 1; 4fd800b3a8 2011-02-23 kinaba: int Y0 = 0; 4fd800b3a8 2011-02-23 kinaba: int C = 1; 4fd800b3a8 2011-02-23 kinaba: int D = 1; 4fd800b3a8 2011-02-23 kinaba: int RetVal = 6; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, PerfectRectangles().numberOfRectangles(N, M, X0, A, B, Y0, C, D)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<2>) { 4fd800b3a8 2011-02-23 kinaba: int N = 1; 4fd800b3a8 2011-02-23 kinaba: int M = 1000000; 4fd800b3a8 2011-02-23 kinaba: int X0 = 1; 4fd800b3a8 2011-02-23 kinaba: int A = 2; 4fd800b3a8 2011-02-23 kinaba: int B = 3; 4fd800b3a8 2011-02-23 kinaba: int Y0 = 1; 4fd800b3a8 2011-02-23 kinaba: int C = 4; 4fd800b3a8 2011-02-23 kinaba: int D = 7; 4fd800b3a8 2011-02-23 kinaba: int RetVal = 0; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, PerfectRectangles().numberOfRectangles(N, M, X0, A, B, Y0, C, D)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<3>) { 4fd800b3a8 2011-02-23 kinaba: int N = 10; 4fd800b3a8 2011-02-23 kinaba: int M = 20; 4fd800b3a8 2011-02-23 kinaba: int X0 = 4; 4fd800b3a8 2011-02-23 kinaba: int A = 76; 4fd800b3a8 2011-02-23 kinaba: int B = 2; 4fd800b3a8 2011-02-23 kinaba: int Y0 = 6; 4fd800b3a8 2011-02-23 kinaba: int C = 2; 4fd800b3a8 2011-02-23 kinaba: int D = 43; 4fd800b3a8 2011-02-23 kinaba: int RetVal = 12; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, PerfectRectangles().numberOfRectangles(N, M, X0, A, B, Y0, C, D)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<4>) { 4fd800b3a8 2011-02-23 kinaba: int N = 1999; 4fd800b3a8 2011-02-23 kinaba: int M = 4000000; 4fd800b3a8 2011-02-23 kinaba: int X0 = 1000; 4fd800b3a8 2011-02-23 kinaba: int A = 1; 4fd800b3a8 2011-02-23 kinaba: int B = 1; 4fd800b3a8 2011-02-23 kinaba: int Y0 = 0; 4fd800b3a8 2011-02-23 kinaba: int C = 1; 4fd800b3a8 2011-02-23 kinaba: int D = 1; 4fd800b3a8 2011-02-23 kinaba: int RetVal = 1002995; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, PerfectRectangles().numberOfRectangles(N, M, X0, A, B, Y0, C, D)); } 4fd800b3a8 2011-02-23 kinaba: int Test_(Case_<5>) { 4fd800b3a8 2011-02-23 kinaba: int N = 2000; 4fd800b3a8 2011-02-23 kinaba: int M = 4000000; 4fd800b3a8 2011-02-23 kinaba: int X0 = 1500; 4fd800b3a8 2011-02-23 kinaba: int A = 1; 4fd800b3a8 2011-02-23 kinaba: int B = 1; 4fd800b3a8 2011-02-23 kinaba: int Y0 = 500; 4fd800b3a8 2011-02-23 kinaba: int C = 1; 4fd800b3a8 2011-02-23 kinaba: int D = 1; 4fd800b3a8 2011-02-23 kinaba: int RetVal = 1003997; 4fd800b3a8 2011-02-23 kinaba: return verify_case(RetVal, PerfectRectangles().numberOfRectangles(N, M, X0, A, B, Y0, C, D)); } 4fd800b3a8 2011-02-23 kinaba: template<int N> void Run_() { cerr << "Test Case #" << N << "..." << flush; Test_(Case_<N>()); Run_<sizeof(Test_(Case_<N+1>()))==1 ? -1 : N+1>(); } 4fd800b3a8 2011-02-23 kinaba: template<> void Run_<-1>() {} 4fd800b3a8 2011-02-23 kinaba: int main() { Run_<0>(); } 4fd800b3a8 2011-02-23 kinaba: // END CUT HERE 4fd800b3a8 2011-02-23 kinaba: