poj3292(筛法+打表)

题目链接:https://vjudge.net/problem/POJ-3292

题意:定义4n+1数(简称H数),H数分为三类:unit,即为1; H-primes,只能分解为1×自身,类似于我们平时说的素数; H-composites,除unit和H-primes数以外的H数。输入h,求[1,h]之间的H-composites数的个数。

思路:写了我3个多小时,因为题目理解错误和代码错误,写得崩溃。。QAQ。先说我想到的正确解法,注意到H-primes和我们说的素数基本类似,所以我们可以用欧筛法打表求出所有的H-primes,然后打表求出所有的H-composites,方法是枚举所有素数,如果这两个素数的乘积小于1e6+1,则记录为H-composites,要注意的是这里的判断不能写prime1[i]*prime[j]<=1000001,因为prime1[i]*prime[j]可能超出int范围,然后会导致段错误,所以应该除法判断(见代码)。然后对每一组输入h,二分查找<=h的最大H-composites数,它的下标+1即有多少个<=h的H-composites数,即所求结果。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int maxn=1000005;
int h,vis[maxn],prime1[maxn],cnt1,prime2[maxn],cnt2;

void Prime(){
    memset(vis,1,sizeof(vis));
    for(int i=5;i<=1000001;i+=4){
        if(vis[i]) prime1[cnt1++]=i;
        for(int j=0;j<cnt1&&i*prime1[j]<=1000001;++j){
            vis[i*prime1[j]]=0;
            if(i%prime1[j]==0) break;
        }
    }
    memset(vis,0,sizeof(vis));
    for(int i=0;i<cnt1;++i){
        int tmp=1000001/prime1[i];
        for(int j=i;j<cnt1&&prime1[j]<=tmp;++j)
            vis[prime1[i]*prime1[j]]=1;
    }
    for(int i=5;i<=1000001;i+=4)
        if(vis[i])
            prime2[cnt2++]=i;
}

int bs(int x){
    if(x<25) return 0;
    int l=0,r=cnt2-1,m;
    while(l<=r){
        m=(l+r)>>1;
        if(x>=prime2[m]&&x<prime2[m+1]) break;
        if(x<prime2[m]) r=m-1;
        else l=m+1;
    }
    return m+1;
}

int main(){
    Prime();
    prime2[cnt2]=0x3f3f3f3f;
    while(~scanf("%d",&h),h){
        printf("%d ",h);
        printf("%d\n",bs(h));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/FrankChen831X/p/10699960.html

时间: 2024-08-25 21:15:02

poj3292(筛法+打表)的相关文章

POJ_3421_X-factor Chains(素数筛法)

X-factor Chains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5659   Accepted: 1786 Description Given a positive integer X, an X-factor chain of length m is a sequence of integers, 1 = X0, X1, X2, -, Xm = X satisfying Xi < Xi+1 and Xi

poj3292

Semi-prime H-numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8677   Accepted: 3793 Description This problem is based on an exercise of David Hilbert, who pedagogically suggested that one study the theory of 4n+1 numbers. Here, we

hdu 5317 RGCDQ 筛法+线段树解法

RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 299    Accepted Submission(s): 151 Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and mor

POJ 3604 Professor Ben(合数唯一分解,筛法素数表)

这题的大意就是 给出一个数n, 找到它所有的因子, 然后把这些(因子的因子数)的立方和求出来. 题目的时限虽然很宽,但是数据很BT.首先,公式必须找出来. 证明如下: 先将n质因数分解成形如n = a ^m * b ^ p * c ^q *........; 那么要求的结果为函数g(x)的值; 我们以n有2个质因数为例子: g(n) = g(a ^m  *  b ^p ) ; 设求因子个数的立方的函数为f(x); 然后找到所有的因子并计算和; g(a ^ m  *  b  ^ p ) = f(

找新朋友

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8315    Accepted Submission(s): 4368 Problem Description 新年快到了,“猪头帮协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是

binary_search算法

在计算机科学中,折半搜索(英语:half-interval search),也称二分查找算法(binary search).二分搜索法.二分搜索.二分探索,是一种在有序数组中查找某一特定元素的搜索算法.搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束:如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较.如果在某一步骤数组为空,则代表找不到.这种搜索算法每一次比较都使搜索范围缩小一半. 递归版: 1 int

NOIP算法总结

前言 离NOIP还有一个星期,匆忙的把寒假整理的算法补充完善,看着当时的整理觉得那时还年少.第二页贴了几张从贴吧里找来的图片,看着就很热血的.旁边的同学都劝我不要再放PASCAL啊什么的了,毕竟我们的下一级直接学C++.即便我本人对C++也是赞赏有加,不过PASCAL作为梦的开始终究不能忘记.不像机房中其余的OIERS,我以后并不想学计算机类的专业.当年来学这个竞赛就是为了兴趣,感受计算机之美的.经过时迁,计划赶不上变化,现在尚处于迷茫之中,也很难说当时做的决定是对是错.然而我一直坚信迷茫的时候

POJ 2154 【POLYA】【欧拉】

前记: TM终于决定以后干啥了.这几天睡的有点多.困饿交加之间喝了好多水.可能是灌脑了. 切记两件事: 1.安心当单身狗 2.顺心码代码 题意: 给你N种颜色的珠子,串一串长度问N的项链,要求旋转之后重合的算是同一种项链.问一共有多少中可能.结果模p. 1 <= N <= 1000000000, 1 <= P <= 30000 思路: 首先是我们的POLYA定理,给定的公式是这样的sigma(N^gcd(N,i))/N   i从0到N-1. 然后是优化的问题.因为如果我们枚举i累加

UVa 11064 - Number Theory

题目:求给顶一个数n,的所有的1 ≤ m ≤ n的m,使得gcd(m,n)≠ 1 且 gcd(m,n)≠ m. 分析:数论,素数筛法,欧拉函数. 设pi为n的第i个素数因,k1为第i个素数因子的个数,则有: 1 ≤ m ≤ n,gcd(m,n)= 1 的m的个数为欧拉函数: 欧拉函数:φ(n)= n *(1 - 1/p1)*(1 - 1/p2)*(1 - 1/p3)*-*(1 - 1/pt): 1 ≤ m ≤ n,gcd(m,n)= m 的m的个数为n的所有因数的个数: 因数个数:f(n)= (