hdu5317(2015多校3)--RGCDQ(素数筛+枚举)

题目链接:点击打开链接

题目大意:定义f(i)为组成i的素数的种类,求在区间[l,r]内的gcd(f(i),f(j))  (l <= i < j <= r)的最大值

素数筛筛出10^6内的素数,求出每一个数的f(i),可以发现f(i) <= 7,用一个数组统计一下s[i][j]从2到i内f(x)=j有多少个,在计算区间的时候直接相减,判断一下最大的gcd

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std ;
#define LL __int64
#define maxn 1000000+10
int a[maxn] , check[maxn] ;
int tot ;
int num[maxn] ;
int s[maxn][10] ;
void get_pri() {
    int i , j ;
    tot = 0 ;
    memset(check,0,sizeof(check)) ;
    for(i = 2 ; i <= 1000000 ; i++) {
        if( !check[i] ) a[tot++] = i ;
        for(j = 0 ; j < tot ; j++) {
            if( i*a[j] >= 1000000 ) break ;
            check[ i*a[j] ] = 1 ;
            if( i%a[j] == 0 ) break ;
        }
    }
}
int f(int x) {
    int j , cnt = 0 ;
    for(j = 0 ; a[j]*a[j] <= x ; j++) {
        if( x%a[j] == 0 ) cnt++ ;
        while( x%a[j] == 0 )
            x /= a[j] ;
        if( x == 1 ) break ;
    }
    if( x != 1 ) cnt++ ;
    return cnt ;
}
int main() {
    int t , l , r ;
    int i , j , ans ;
    get_pri() ;
    for(i = 2 ; i <= 1000000 ; i++)
        num[i] = f(i) ;
    memset(s,0,sizeof(s)) ;
    for(i = 2; i <= 1000000 ; i++) {
        for(j = 1 ; j <= 7 ; j++)
            s[i][j] = s[i-1][j] ;
        s[i][ num[i] ]++ ;
    }
    scanf("%d", &t) ;
    while( t-- ) {
        scanf("%d %d", &l, &r) ;
        ans = 1 ;
        for(i = 1 ; i <= 7 ; i++) {
            s[0][i] = s[r][i]-s[l-1][i] ;
            if( s[0][i] > 1 ) ans = i ;
        }

        if( s[0][3]+s[0][6] == 2 )
            ans = max(ans,3) ;
        if( s[0][2]+s[0][4]+s[0][6] >= 2 )
            ans = max(ans,2) ;
        printf("%d\n", ans) ;
    }
    return 0 ;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 23:26:59

hdu5317(2015多校3)--RGCDQ(素数筛+枚举)的相关文章

HDU 5317(2015多校3)-RGCDQ(数论)

题目地址:HDU 5371 题意:每次T(1000000)次询问,每次询问有一个区间[L, R] (2 <= L < R <= 1000000 ). f(i) 表示的是数i的素因子种类数. 然后求这个区间内GCD(f(i), f(j))的最大值,(L <= i < j <= R ). 思路:2*3*5*7*9*11*13=270270<1e6<2*3*5*7*9*11*13*17=4594590.所以f的最大值为7.开一个cnt[ maxn ] [ 8 ]

hdu 5358 First One 2015多校联合训练赛#6 枚举

First One Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 142    Accepted Submission(s): 37 Problem Description soda has an integer array a1,a2,-,an. Let S(i,j) be the sum of ai,ai+1,-,aj. No

POJ 2635 The Embarrassed Cryptographer (同余线性方程+素数筛)

题目地址:POJ 2635 先用素数筛把10^6万以内素数筛出来.然后把输入的那个大数转化成数组,并且每三位存成一个数,这样可以节约内存和时间,然后利用同余线性的原理,对那个小整数以内的所有素数枚举,然后判断是否整除,找到最小的能被整除的. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #i

素数筛 模板

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 int prim[3000000]={2,3,5}; 8 //素数是分为基本素数{2,3}.阳素数{6N+1,N>=1}形式的.阴素数{6N-1,N>=1}形式的 9 //为了代码的好写,在这里这样写的 : 10 //数除了{2,3,5}为素数,其他的数可以写成6N,6N+1

素数筛&amp;&amp;欧拉筛 BZOJ2818 Gcd BZOJ2190 [SDOI2008]仪仗队

折腾了一晚上很水的数论,整个人都萌萌哒 主要看了欧拉筛和素数筛的O(n)的算法 这个比那个一长串英文名的算法的优势在于没有多次计算一个数,也就是说一个数只筛了一次,主要是在%==0之后跳出实现的,具体的解释看的迷迷糊糊,特别是欧拉函数的求解 http://blog.csdn.net/lerenceray/article/details/12420725 代码如下 1 void ES(){ 2 for(int i=2;i<n;i++){ 3 if (!pd[i]){ 4 prime[++top]=

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)

HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分相同,第一部分与第二部分对称. 现在给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法,求出以第i个点为中心的回文串长度,记录到数组p中 要满足题目所要求的内容,需要使得两个相邻的回文串,共享中间的一部分,也就是说,左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也是一样. 因为我们已经记录下来以

素数筛

这是我目前知道的打素数表最快的方法了----  差不多是O(n)的,100000以内花了0.005秒. 1 int prime[100005], np, vis[100005]; 2 3 void get_prime(int n){ 4 mset(prime); mset(vis); 5 np = 0; 6 for(int i = 2; i < n; i++){ 7 if(vis[i] != 1) 8 prime[np++] = i; 9 for(int j = 0, t; j < np &a

HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&amp;#39;s problem(manacher+二分/枚举)

pid=5371">HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分同样,第一部分与第二部分对称. 如今给你一个长为n(n<10^5)的序列,求出该序列中N序列的最大长度. 思路: 来自官方题解:修正了一些题解错别字(误 先用求回文串的Manacher算法.求出以第i个点为中心的回文串长度.记录到数组p中 要满足题目所要求的内容.须要使得两个相邻的回文串,共享中间的一部分,也就是说.左边的回文串长度的一半,要大于等于共享部分的长度,右边回文串也

ACdream 1112 Alice and Bob (sg函数的变形+素数筛)

题意:有N个数,Alice 和 Bob 轮流对这些数进行操作,若一个数 n=a*b且a>1,b>1,可以将该数变成 a 和 b 两个数: 或者可以减少为a或b,Alice先,问谁能赢 思路:首先单看对每个数进行除法的操作,我们可以知道其实是在除以每个数的素因子或素因子之间的积 比如 70=2*5*7 我们可以变成 10(2*5)或 14(2*7) 或 35(5*7)或 2 或 5 或 7 或 1 这七种状态 当我们把他们(2,5,7)当作3个石子也就是一堆时,然而实际上我们是将这堆石子进行ni