标签:style blog http color io os ar for sp
注意到每个区间生存下来的蚂蚁的长度等于区间的gcd
于是可以先预处理出区间的gcd
然后二分查找就好了
预处理gcd我这里用的是倍增法
总的时间复杂度O(NlogN)
/* Cf 271F 倍增求区间GCD 对下标二分 时间复杂度O(NlogN) */ #include <iostream> #include <algorithm> #include <vector> #include <map> using namespace std; const int MAXN = 100009; int st[MAXN][20]; int n, t; map<int, int> pos; vector<int> f[MAXN]; inline int gcd (int x, int y) { return y == 0 ? x : gcd (y, x % y); } inline void ST() { for (int i = n - 1; i > 0; --i) for (int j = 1; i + (1 << j) <= n; j++) st[i][j] = gcd (gcd (st[i][j], st[i][j - 1]), st[i + (1 << j - 1)][j - 1]); } inline int getgcd (int l, int r) { int tem = st[l][0]; for (int k = 0; l + (1 << k) <= r; k++) tem = gcd (gcd (tem, st[l][k]), st[r - (1 << k) + 1][k]); return tem; } int main() { ios::sync_with_stdio (0); cin >> n; int tol = 0; for (int i = 1; i <= n; i++) { cin >> st[i][0]; if (pos.find (st[i][0]) == pos.end() ) tol++, pos[st[i][0]] = tol; f[pos[st[i][0]]].push_back (i); } ST(); cin >> t; for (int i = 1, l, r; i <= t; i++) { cin >> l >> r; int key = getgcd (l, r), k = pos[key]; int d = upper_bound (f[k].begin(), f[k].end(), r) - lower_bound (f[k].begin(), f[k].end(), l); cout << r - l - d +1<< endl; } }
标签:style blog http color io os ar for sp
原文地址:http://www.cnblogs.com/keam37/p/4009856.html