Root Value#13065

Root Value (Editorial)

solution:

First, for an integer , let it's prime factorization be:

x = p_1^{\alpha_1} \cdot p_2^{\alpha_2} \times ... \times p_n^{\alpha_n}

For an integer , \sqrt[m]{x} = x^{\frac{1}{m}} , so

\sqrt[m]{x} = p_1^{\frac{\alpha_1}{m}} \times p_2^{\frac{\alpha_2}{m}} \times ... \times p_n^{\frac{\alpha_n}{m}}

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

a_l \times a_{l+1} \times ... \times a_r = p_1^{\alpha_{l,1} + \alpha_{l+1,1}+...+\alpha_{r,1}} \times ... \times p_n^{\alpha_{l,n} + \alpha_{l+1,n}+...+\alpha_{r,n}}

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;
        }
    }
}