查询区间最小值问题(查询区间gcd也可以)
d[i][j]表示从i开始,长度为2^j的最小值
递推式:d[i][j] = min(d[i][j - 1] , d[i + 2^(j - 1)][j - 1])
初始化:d[i][0] = a[i]
预处理O(nlog(n)) 查询O(1)
1 void ST_init(int n) 2 { 3 for(int i = 1; i <= n; i++)d[i][0] = a[i];//下标从1-n 4 for(int j = 1; (1 << j) <= n; j++) 5 { 6 for(int i = 1; i + (1 << j) - 1 <= n; i++) 7 d[i][j] = min(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]); 8 } 9 } 10 int query(int l, int r) 11 { 12 int k = 0; 13 while((1 << (k +1)) <= r - l + 1)k++; 14 return min(d[l][k], d[r - (1 << k) + 1][k]); 15 }