int[][] m = process(a);
query(i,j,m,a);
public static int query(int i,int j,int[][] m, int[] a) {
int k = binlog(j-i+1);
return Math.min(a[m[i][k]], a[m[j+1-(1<<k)][k]]);
}
public static int binlog( int bits ) // returns 0 for bits=0
{
int log = 0;
if( ( bits & 0xffff0000 ) != 0 ) { bits >>>= 16; log = 16; }
if( bits >= 256 ) { bits >>>= 8; log += 8; }
if( bits >= 16 ) { bits >>>= 4; log += 4; }
if( bits >= 4 ) { bits >>>= 2; log += 2; }
return log + ( bits >>> 1 );
}
private static int[][] process(int[] a) {
int n = a.length;
int[][] m = new int[n][binlog(n)+1];
//initialize M for the intervals with length 1
for (int i = 0; i < n; i++)
m[i][0] = i;
//compute values from smaller to bigger intervals
for (int j = 1; 1 << j <= n; j++)
for (int i = 0; i + (1 << j) - 1 < n; i++)
if (a[m[i][j - 1]] < a[m[i + (1 << (j - 1))][j - 1]])
m[i][j] = m[i][j - 1];
else
m[i][j] = m[i + (1 << (j - 1))][j - 1];
return m;
}
No comments:
Post a Comment