File Annotation
Not logged in
23dfcca431 2011-02-23        kinaba: //-------------------------------------------------------------
23dfcca431 2011-02-23        kinaba: // Range Minimum Query
23dfcca431 2011-02-23        kinaba: //   O(N log N) construction
cd0467fefc 2012-07-22        kinaba: //   O(log N) per each query
23dfcca431 2011-02-23        kinaba: //
23dfcca431 2011-02-23        kinaba: // Verified by
23dfcca431 2011-02-23        kinaba: //   - SRM337 Div1 LV2
23dfcca431 2011-02-23        kinaba: //   - SRM431 Div1 LV3
cd0467fefc 2012-07-22        kinaba: //   - Codeforces 129 Div1 E
23dfcca431 2011-02-23        kinaba: //-------------------------------------------------------------
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: template<typename T>
23dfcca431 2011-02-23        kinaba: struct RMQ
23dfcca431 2011-02-23        kinaba: {
23dfcca431 2011-02-23        kinaba: 	vector< vector<int> > rm;
23dfcca431 2011-02-23        kinaba: 	vector<T> d;
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: 	RMQ( const vector<T>& d ) : d(d) {
23dfcca431 2011-02-23        kinaba: 		int n = d.size();
23dfcca431 2011-02-23        kinaba: 
23dfcca431 2011-02-23        kinaba: 		// rm[k][x] = i s.t. d[i] is the minimum in [x, x+2^k)
23dfcca431 2011-02-23        kinaba: 		rm.push_back( vector<int>(n) );
23dfcca431 2011-02-23        kinaba: 		for(int x=0; x<n; ++x)
23dfcca431 2011-02-23        kinaba: 			rm[0][x] = x;
23dfcca431 2011-02-23        kinaba: 		for(int k=1; (1<<k)<=n; ++k) {
23dfcca431 2011-02-23        kinaba: 			rm.push_back( rm[k-1] );
23dfcca431 2011-02-23        kinaba: 			for(int x=0; x+(1<<k-1)<n; ++x)
23dfcca431 2011-02-23        kinaba: 				if( d[rm[k][x]] > d[rm[k-1][x + (1<<k-1)]] )
23dfcca431 2011-02-23        kinaba: 					rm[k][x] = rm[k-1][x + (1<<k-1)];
23dfcca431 2011-02-23        kinaba: 		}
23dfcca431 2011-02-23        kinaba: 	}
23dfcca431 2011-02-23        kinaba: 
cd0467fefc 2012-07-22        kinaba: 	// min {i in [L,R] | d[i] is minumum among d[L..R]}
cd0467fefc 2012-07-22        kinaba: 	int operator()(int L, int R) const {
23dfcca431 2011-02-23        kinaba: 		int k=0;
23dfcca431 2011-02-23        kinaba: 		for(; L+(1<<k) < R-(1<<k)+1; ++k) {}
cd0467fefc 2012-07-22        kinaba: 		int i = rm[k][L];
cd0467fefc 2012-07-22        kinaba: 		int j = rm[k][R-(1<<k)+1];
23dfcca431 2011-02-23        kinaba: 		return (d[i]<=d[j] ? i : j);
23dfcca431 2011-02-23        kinaba: 	}
23dfcca431 2011-02-23        kinaba: 
cd0467fefc 2012-07-22        kinaba: 	// {i in [L,R] | d[i] is minumum among d[L..R]}
23dfcca431 2011-02-23        kinaba: 	vector<int> all(int L, int R) const {
23dfcca431 2011-02-23        kinaba: 		vector<int> ans;
23dfcca431 2011-02-23        kinaba: 		int minValue = d[(*this)(L, R)];
23dfcca431 2011-02-23        kinaba: 		while( L <= R ) {
23dfcca431 2011-02-23        kinaba: 			int C = (*this)(L, R);
23dfcca431 2011-02-23        kinaba: 			if( minValue < d[C] )
23dfcca431 2011-02-23        kinaba: 				break;
23dfcca431 2011-02-23        kinaba: 			ans.push_back(C);
23dfcca431 2011-02-23        kinaba: 			L = C+1;
23dfcca431 2011-02-23        kinaba: 		}
23dfcca431 2011-02-23        kinaba: 		return ans;
cd0467fefc 2012-07-22        kinaba: 	}
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 	// max {i in [L,R] | d[i]<X}, or -1
cd0467fefc 2012-07-22        kinaba: 	int rightmost_less_than_X(int L, int R, T X) const {
cd0467fefc 2012-07-22        kinaba: 		if(L>R) return -1;
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 		int k=0;
cd0467fefc 2012-07-22        kinaba: 		for(; L+(1<<k) < R-(1<<k)+1; ++k) {}
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 		int i = rm[k][L];
cd0467fefc 2012-07-22        kinaba: 		int j = rm[k][R-(1<<k)+1];
cd0467fefc 2012-07-22        kinaba: 		if( !(d[i]<X || d[j]<X) )
cd0467fefc 2012-07-22        kinaba: 			return -1;
cd0467fefc 2012-07-22        kinaba: 		if( d[j] < X )
cd0467fefc 2012-07-22        kinaba: 			L = R-(1<<k)+1;
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 		for(; k; --k) { // Answer is in [L, L+(1<<k))
cd0467fefc 2012-07-22        kinaba: 			i = rm[k-1][L];
cd0467fefc 2012-07-22        kinaba: 			j = rm[k-1][L+(1<<k-1)];
cd0467fefc 2012-07-22        kinaba: 			if( d[j] < X )
cd0467fefc 2012-07-22        kinaba: 				L += 1<<k-1;
cd0467fefc 2012-07-22        kinaba: 		}
cd0467fefc 2012-07-22        kinaba: 		return L;
cd0467fefc 2012-07-22        kinaba: 	}
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 	// min {i in [L,R] | d[i]<X}, or -1
cd0467fefc 2012-07-22        kinaba: 	int leftmost_less_than_X(int L, int R, T X) const {
cd0467fefc 2012-07-22        kinaba: 		if(L>R) return -1;
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 		int k=0;
cd0467fefc 2012-07-22        kinaba: 		for(; L+(1<<k) < R-(1<<k)+1; ++k) {}
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 		int i = rm[k][L];
cd0467fefc 2012-07-22        kinaba: 		int j = rm[k][R-(1<<k)+1];
cd0467fefc 2012-07-22        kinaba: 		if( !(d[i]<X || d[j]<X) )
cd0467fefc 2012-07-22        kinaba: 			return -1;
cd0467fefc 2012-07-22        kinaba: 		if( !(d[i] < X) )
cd0467fefc 2012-07-22        kinaba: 			L = R-(1<<k)+1;
cd0467fefc 2012-07-22        kinaba: 
cd0467fefc 2012-07-22        kinaba: 		for(; k; --k) { // Answer is in [L, L+(1<<k))
cd0467fefc 2012-07-22        kinaba: 			i = rm[k-1][L];
cd0467fefc 2012-07-22        kinaba: 			j = rm[k-1][L+(1<<k-1)];
cd0467fefc 2012-07-22        kinaba: 			if( !(d[i] < X) )
cd0467fefc 2012-07-22        kinaba: 				L += 1<<k-1;
cd0467fefc 2012-07-22        kinaba: 		}
cd0467fefc 2012-07-22        kinaba: 		return L;
23dfcca431 2011-02-23        kinaba: 	}
23dfcca431 2011-02-23        kinaba: };