1470-区间求最值(ST算法+因子个数) ZCMU

Description

   给定一个长度为N 的数组,有q个询问,每个询问是求在数组的一段区间内那个元素的因子的个数最大,比如24的因子的个数就是8。 

Input

  首先是一个整数t,表示有t组测试数据,每组测试数据的第一行是一个整数N(1<=N<=10^6),第二行有N个整数ai(1<=ai<=10^6,i=1,2,.....N)表示数组的元素。第三行有一个整数q(1<=q<=10^5),代表有q个询问,接下来每一行有两个整数,li,ri(li<=ri,li>=1,ri<=N).代表数组的一段区间,并且li+1>=li,ri+1>=ri。

Output

对于每组数据的每个询问都输出一个整数表示在这段区间里面元素因子个数的最大值。

Sample Input

1

10

2 3 5 6 9 11 12 36 39 44

3

2 6

3 8

3 9

Sample Output

4

9

9

解析

 区间求最值(RMQ问题)的求解算法--ST算法+快速求数的因子个数的算法,具体算法详解请上网浏览。

代码

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define MAX 1000005
#define N 30
int Log[MAX],ans[MAX][N],num[MAX];
int n,que,x,y;
//求因子个数算法
int solve(int x)
{
    if(x==1) return 1;
    int sum=2,temp=sqrt(x);
    for(int i=2;i<=temp;i++)
    {
        if(x%i==0)
        {
            if(i==temp&&x/i==i)
                sum+=1;
            else
                sum+=2;
        }
    }
    return sum;
}
int main()
{
    int i,j,c,T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&c);
            num[i]=solve(c);
        }
        Log[0]=-1;
        //以下为ST算法核心代码
        for(i=1;i<=n;i++)
        {
            ans[i][0]=num[i];
            Log[i]=Log[i>>1]+1;
        }
        for(j=1;j<=N;j++)
        {
            for(i=1;i+(1<<j)-1<=n;i++)
            {
                ans[i][j]=max(ans[i][j-1],ans[i+(1<<j-1)][j-1]);
            }
        }
        scanf("%d",&que);
        while(que--)
        {
            scanf("%d%d",&x,&y);
            int temp=Log[y-x+1];
            printf("%d\n",max(ans[x][temp],ans[y-(1<<temp)+1][temp]));
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ZCMU_2024/article/details/81605987
今日推荐