solution:
First, for an integer , let it's prime factorization be:
For an integer , \sqrt[m]{x} = x^{\frac{1}{m}} , so
So \sqrt[m]{x} would be a natural number if and only if is a common divisor of \alpha_1 , \alpha_2 , ... , \alpha_n.
Since we need the maximum , the answer would be \gcd(\alpha_1 , \alpha_2 , ... , \alpha_n) , where \alpha_i is the power of the i_{\text{th}} prime.
Now to find for a range , we know that
where \alpha_{i,j} is the power of the j_{\text{th}} prime in the i_{\text{th}} number.
Since a_i \le 200, there are at most prime numbers. Let \mathsf{pre}[i][j] be the prefix sum until index for the j_{\text{th}} prime.
The answer for a query () would be:
\gcd(\mathsf{pre}[r][1] - \mathsf{pre}[l-1][1] , \mathsf{pre}[r][2] - \mathsf{pre}[l-1][2] , ... , \mathsf{pre}[r][47] - \mathsf{pre}[l-1][47])
Time Complexity : \mathcal{O}(47\cdot(n + q)).
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define F first
#define S second
using namespace std;
const int N = 2e5 + 1;
const int M = 1e9 + 7;
signed main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
vector<int>primes;
primes.push_back(2);
for(int i=3;i<=200;i++)
{
bool ok = 1;
for(int j=2;j*j<=i;j++)
{
if(i % j == 0)
ok = 0;
}
if(ok)
primes.push_back(i);
};
int tc = 1;
cin>>tc;
while(tc--)
{
int n,q;
cin>>n>>q;
int a[n+1] , pre[n+1][primes.size() + 1];
memset(pre,0,sizeof pre);
for(int i=1;i<=n;i++)
{
cin>>a[i];
for(int j=0;j<primes.size();j++)
{
while(a[i] % primes[j] == 0)
{
pre[i][j]++;
a[i] /= primes[j];
}
}
}
for(int j=0;j<primes.size();j++)
{
for(int i=1;i<=n;i++)
{
pre[i][j] += pre[i-1][j];
}
}
while(q--)
{
int l,r;
cin>>l>>r;
int ans = 0;
for(int j=0;j<primes.size();j++)
ans = __gcd(ans , pre[r][j] - pre[l-1][j]);
cout<<ans<<endl;
}
}
}