HDU 5317 RGCDQ

想法型数论题,题意很简单,就不多说了,首先想的时候认为算出所有数字的质因子个数会超时就没多想,结果跪了好久,最后仔细一想发现需要的时间也不多才想到该怎么做。

本题的突破点是,每个数字的质因子的个数只可能在8以下,非常小,打表算出每个数字的质因子的个数之后,记录下每个数字之下质因子个数是1~8的数的个数分别是多少个,然后R和L的这写记录数做差之后就知道R和L之间质因数个数是1~8之间的数分别有多少个,再加上几个判断就ok~

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <functional>
#include <cstdio>
#include <queue>
#include <map>
#include <algorithm>
#include <stack>
#include <utility>
typedef long long ll;
using namespace std;
const int mx = 1000009;
const int N = 1009;
int p[mx >> 1],cnt;
bool tage[mx];
int a[mx],num[mx][10],gc[10];
void get_prime()
{
    int i,j,k;
    cnt = 0;
    memset(num,0,sizeof(num));
    memset(a,0,sizeof(a));
    memset(tage,false,sizeof(false));
    for(i = 2; i < mx; i++)
    {
        if(!tage[i]) p[cnt++] = i;
        for(j = 0; j < cnt && i * p[j] < mx; j++)
        {
            tage[i * p[j]] = 1;
            if(i % p[j] == 0)
                break;
        }
    }
    for(i = 0;i < cnt;i++)
        {
            k = p[i];
            while(k < mx)
            {
                a[k]++;
                k += p[i];
            }
        }
    for(i = 2; i < mx; i++)
    {
//        printf("i = %d a  =%d \n",i,a[i]);
        for(j = 1; j < 10; j++)
        {
            if(a[i] == j)
                num[i][j] = num[i - 1][j] + 1;
            else
                num[i][j] = num[i - 1][j];
        }
    }
}


int main ()
{
    int i,j,L,R,T,ans;
    get_prime();
    scanf("%d",&T);
    while(T--)
    {
        ans = 0;
        scanf("%d%d",&L,&R);
        for(i = 1; i < 10; i++)
            gc[i] = num[R][i] - num[L - 1][i];
        for(i = 9; i > 0 && !ans; i--)
            if(gc[i] > 1)
                ans = i;
        if(gc[4] && gc[8])
            ans = max(ans,4);
        if(gc[4] && gc[2])
            ans = max(ans,2);
        if(gc[2] && gc[8])
            ans = max(ans,2);
        if(ans == 0)
            ans = max(ans,1);
        printf("%d\n",ans);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值