int pri[maxn], cnt, mu[maxn]; bool isp[maxn]; vector<int> D[maxn]; voidinit_isp(int n){ mu[1] = 1; for (int i = 2; i <= n; ++i) { if (!isp[i]) pri[++cnt] = i, mu[i] = -1; for (int j = 1; j <= cnt && i * pri[j] <= n; ++j) { isp[i * pri[j]] = 1; if (i % pri[j] == 0) break; mu[i * pri[j]] = -mu[i]; } } for (int i = 1; i <= n; ++i) for (int j = i; j <= n; j += i) D[j].push_back(i); }
int n, a[maxn], b[maxn]; vector<int> A[maxn], B[maxn];
int ans[maxn]; voidsolve(){ auto cmpa = [](constint &u, constint &v) { return a[u] < a[v]; }; auto cmpb = [](constint &u, constint &v) { return b[u] < b[v]; }; for (int t = 1; t <= n; ++t) { sort(A[t].begin(), A[t].end(), cmpa); sort(B[t].rbegin(), B[t].rend(), cmpb); stack<int> S; vector<int> cnt(n / t + 1); for (auto y : B[t]) { S.push(y); for (auto d : D[y / t]) ++cnt[d]; } for (auto x : A[t]) { int res = 0; for (auto d : D[x / t]) res += mu[d] * cnt[d]; while (!S.empty() && (b[S.top()] <= a[x] || res)) { int y = S.top(); S.pop(); for (auto d : D[y / t]) { if (x / t % d == 0) res -= mu[d]; --cnt[d]; } if (gcd(x / t, y / t) == 1) ans[t] = max(ans[t], b[y] - a[x]); } } } }