题意:
找出一个p,让这个p尽可能多得整除区间内的数,问这个p最多能整除区间内的多少个数。
思路:
把每个数分解质因数,转化成求区间众数,进而使用莫队解决。
// Decline is inevitable,
// Romance will last forever.
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pii pair<int,int>
#define pb push_back
#define fi first
#define se second
#define ll long long
#define LL long long
//#define int long long
#define endl '\n'
const int maxn = 5e4 + 10;
const int maxm = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int dx[] = {0, 0, -1, 1}; //{0, 0, 1, 1, 1,-1,-1,-1}
const int dy[] = {1, -1, 0, 0}; //{1,-1, 1, 0,-1, 1, 0,-1}
const int P = 998244353;
struct Query {
int l, r, id, pos; //
bool operator < (const Query &x) const {
if(pos == x.pos) {
if(x.pos & 1)
return r < x.r;
return r > x.r;
}
return pos < x.pos;
}
}q[maxn];
int b[maxn], n, m;
vector<int> g[maxn];
int cnt[maxm], ans[maxn], maxx, num[maxm]; //num[i]表示当前区间内数量为i的数一共有多少个
void add(int pos) {
for(auto i : g[pos]) {
num[cnt[i]]--;
cnt[i]++;
num[cnt[i]]++;
maxx = max(maxx, cnt[i]);
}
}
void del(int pos) {
for(auto i : g[pos]) {
num[cnt[i]]--;
if(maxx == cnt[i] && num[cnt[i]] == 0)
maxx--;
cnt[i]--;
num[cnt[i]]++;
}
}
void get_fac(int n, vector<int> &C) { //返回值s是质因子个数 同时将相同质因子存入C
C.clear();
for (int i = 2; i * i <= n; i++) {
if(n % i == 0) {
C.push_back(i);
while(n % i == 0) n /= i;
}
}
if (n > 1) C.push_back(n);
}
void solve() {
maxx = 0;
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> b[i];
for(int i = 1; i <= n; i++) {
get_fac(b[i], g[i]);
}
int sq = (int)sqrt(n);
for(int i = 1; i <= m; i++) {
cin >> q[i].l >> q[i].r;
q[i].id = i;
q[i].pos = (q[i].l - 1) / sq + 1;
}
sort(q + 1, q + m + 1);
int l = 1, r = 0;
for(int i = 1; i <= m; i++) {
while(l > q[i].l) add(--l);
while(r < q[i].r) add(++r);
while(l < q[i].l) del(l++);
while(r > q[i].r) del(r--);
ans[q[i].id] = maxx;
}
for(int i = 1; i <= m; i++) cout << ans[i] << endl;
while (l <= r) del(l++);
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int T; cin >> T; while(T--)
solve();
return 0;
}