1. 程式人生 > >Redraiment猜想----米勒拉賓+分塊打表

Redraiment猜想----米勒拉賓+分塊打表

Redraiment猜想

Description

redraiment在家極度無聊,於是找了張紙開始統計素數的個數。 設函式f(n)返回從1->n之間素數的個數。 redraiment發現: f(1) = 0 f(10) = 4 f(100) = 25 ... 滿足g(m) = 17 * m2 / 3 - 22 * m / 3 + 5 / 3 其中m為n的位數。 他很激動,是不是自己發現了素數分佈的規律了! 請你設計一個程式,求出1->n範圍內素數的個數,來驗證redraiment是不是正確的,也許還可以得諾貝爾獎呢。^_^

Input

輸入包括多組資料。 每組資料僅有一個整數n (1≤n≤100000000)。 輸入以0結束

Output

對於每組資料輸入,輸出一行,為1->n(包括n)之間的素數的個數。

 

解題思路:

輸入n  輸出n以內的素數個數 我們很容易想到   我們用埃氏篩選法篩選出素數 然後再統計一個字首和  就ok了

但是 這個題 n的範圍是1e8   陣列沒辦法開這麼大 所以 這個方法不行了

我們只好換一個方法   想到了 分塊打表

把1e8 分成每10000 為一塊    我們統計出每隔一萬個數字  的素數個數

(就是 把1到一萬的素數個數存下來   一萬到兩萬存下來   兩萬到三萬存下來。。。。以此類推)

那麼我們就把1e8分成了(1e8/10000)=1e4 塊

我們做一個字首和  得到這一萬個數的字首和    每個數代表的就是   n*10000 以內的素數個數

那麼每次詢問 我們就找到最近的10000的倍數   然後暴力統計剩下的素數個數就好了

方法呢就是這個方法

但是如果你用最普通的方法打表  可能需要好幾十分鐘 甚至個把小時 才能打出來表

即使你說 你有時間 硬要用樸素法槓這道題  那麼就算你花一個小時打出了表 下邊還是會錯的

 

我用的是米勒拉賓素性檢測演算法來打表   打表倒是很快  打了三四分鐘就出來了

但是  這一萬個數  賦值給陣列  然後交題  提示說 code is too long !

好吧   看來分的塊太小的  改成每塊十萬   打表出來1000個數       這下就ok了

但是這下你每次暴力處理的資料就是十萬了(那麼如果你用樸素法判斷素數還是會超時  所以還是得米勒拉賓。。)

關於米勒拉賓演算法  米勒拉賓演算法詳解+程式碼

 

AC程式碼

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
//分塊打表得到的1000個數
int a[1007]={0,9592,17984,25997,33860,41538,49098,56543,63951,71274,78498,85714,92938,100021,107126,114155,121127,128141,135072,142029,148933,155805,162662,169511,176302,183072,189880,196645,203362,210109,216816,223492,230209,236900,243539,250150,256726,263397,269987,276611,283146,289774,296314,302824,309335,315948,322441,328964,335439,341992,348513,354971,361407,367900,374362,380800,387202,393606,399993,406429,412849,419246,425648,432073,438410,444757,451159,457497,463872,470283,476648,483015,489319,495666,501962,508261,514565,520910,527154,533506,539777,546024,552319,558597,564877,571119,577439,583714,590006,596222,602489,608672,614917,621177,627400,633578,639851,646054,652265,658445,664579,670820,676970,683178,689382,695609,701795,708007,714154,720341,726517,732707,738873,745001,751131,757288,763455,769639,775773,781906,788060,794149,800285,806435,812601,818703,824801,830940,837099,843192,849252,855281,861401,867482,873606,879640,885698,891833,897938,904057,910077,916147,922193,928293,934441,940455,946551,952566,958651,964695,970704,976761,982776,988851,994839,1000862,1006966,1013012,1019012,1025092,1031130,1037119,1043113,1049172,1055139,1061198,1067185,1073198,1079266,1085243,1091314,1097360,1103258,1109288,1115323,1121389,1127407,1133364,1139344,1145305,1151367,1157275,1163205,1169267,1175214,1181158,1187148,1193122,1199102,1205065,1211050,1216988,1222953,1228861,1234873,1240833,1246718,1252693,1258685,1264617,1270607,1276577,1282513,1288409,1294356,1300243,1306226,1312179,1318125,1324046,1329943,1335881,1341795,1347749,1353661,1359631,1365511,1371432,1377385,1383291,1389261,1395148,1401007,1406874,1412758,1418640,1424606,1430531,1436398,1442335,1448221,1454144,1460019,1465935,1471822,1477731,1483609,1489509,1495350,1501220,1507122,1512992,1518898,1524831,1530729,1536569,1542459,1548366,1554245,1560093,1565927,1571812,1577649,1583439,1589324,1595177,1601049,1606876,1612775,1618668,1624527,1630379,1636202,1642052,1647911,1653807,1659690,1665517,1671330,1677200,1683065,1688960,1694762,1700558,1706405,1712204,1718134,1723913,1729764,1735590,1741430,1747297,1753058,1758964,1764767,1770613,1776430,1782260,1788065,1793863,1799676,1805472,1811272,1817102,1822944,1828703,1834530,1840359,1846115,1852006,1857859,1863719,1869536,1875367,1881199,1886923,1892785,1898632,1904396,1910248,1915979,1921714,1927488,1933290,1939089,1944833,1950638,1956440,1962184,1968015,1973815,1979564,1985372,1991162,1996958,2002749,2008561,2014337,2020103,2025864,2031667,2037385,2043192,2048989,2054802,2060577,2066324,2072084,2077862,2083678,2089379,2095092,2100791,2106544,2112215,2118001,2123788,2129473,2135232,2141013,2146775,2152470,2158233,2163998,2169775,2175518,2181266,2187043,2192806,2198505,2204262,2210026,2215731,2221543,2227279,2233036,2238778,2244473,2250226,2255897,2261623,2267395,2273189,2278857,2284633,2290350,2296101,2301840,2307562,2313254,2318966,2324728,2330509,2336299,2342005,2347727,2353448,2359142,2364953,2370696,2376402,2382120,2387828,2393630,2399359,2405101,2410827,2416624,2422305,2427981,2433654,2439371,2445078,2450819,2456577,2462273,2467902,2473603,2479409,2485075,2490756,2496476,2502205,2507850,2513534,2519246,2524898,2530575,2536286,2542018,2547620,2553305,2559020,2564807,2570490,2576200,2581841,2587550,2593245,2598870,2604535,2610226,2615907,2621566,2627281,2632997,2638710,2644301,2649982,2655643,2661384,2667036,2672702,2678429,2684053,2689717,2695450,2701159,2706858,2712494,2718160,2723886,2729508,2735255,2740985,2746679,2752380,2758056,2763691,2769407,2775053,2780731,2786355,2791974,2797652,2803324,2808976,2814698,2820355,2826040,2831693,2837271,2842995,2848642,2854302,2859963,2865596,2871207,2876824,2882545,2888144,2893763,2899408,2905025,2910714,2916338,2921977,2927626,2933208,2938896,2944531,2950188,2955834,2961491,2967186,2972862,2978556,2984185,2989825,2995509,3001134,3006727,3012361,3018013,3023649,3029296,3034973,3040593,3046241,3051875,3057494,3063082,3068712,3074341,3080043,3085615,3091310,3096885,3102560,3108210,3113843,3119506,3125086,3130647,3136324,3141927,3147521,3153171,3158801,3164431,3170052,3175695,3181277,3186966,3192556,3198119,3203713,3209317,3214948,3220576,3226203,3231825,3237408,3242981,3248574,3254129,3259801,3265418,3271006,3276528,3282200,3287879,3293449,3299022,3304658,3310266,3315819,3321475,3327111,3332731,3338330,3343958,3349661,3355218,3360782,3366339,3371952,3377626,3383274,3388854,3394435,3400038,3405629,3411294,3416918,3422475,3428077,3433631,3439220,3444790,3450336,3455970,3461542,3467134,3472756,3478304,3483945,3489523,3495161,3500795,3506314,3511921,3517468,3523035,3528547,3534167,3539757,3545331,3550955,3556550,3562115,3567677,3573237,3578833,3584453,3590054,3595578,3601204,3606812,3612449,3618045,3623569,3629084,3634647,3640201,3645798,3651314,3656875,3662428,3668016,3673600,3679207,3684787,3690317,3695916,3701487,3707015,3712576,3718206,3723740,3729306,3734871,3740435,3746021,3751585,3757186,3762745,3768288,3773903,3779511,3785086,3790643,3796205,3801803,3807345,3812898,3818389,3823937,3829432,3835002,3840554,3846130,3851637,3857201,3862694,3868404,3873874,3879427,3884940,3890503,3896123,3901727,3907301,3912842,3918498,3924009,3929584,3935172,3940685,3946251,3951767,3957296,3962821,3968429,3973996,3979592,3985158,3990671,3996215,4001767,4007342,4012851,4018394,4023969,4029474,4035037,4040549,4046077,4051617,4057149,4062674,4068213,4073713,4079200,4084816,4090382,4095945,4101517,4107066,4112568,4118064,4123596,4129144,4134695,4140216,4145831,4151356,4156813,4162309,4167847,4173373,4178911,4184419,4189971,4195467,4201083,4206661,4212176,4217594,4223154,4228658,4234244,4239815,4245417,4250930,4256409,4261935,4267454,4272940,4278523,4284089,4289594,4295059,4300577,4306121,4311581,4317182,4322713,4328194,4333750,4339254,4344668,4350186,4355687,4361240,4366707,4372244,4377733,4383283,4388818,4394304,4399810,4405341,4410890,4416431,4421976,4427436,4432986,4438498,4444056,4449611,4455090,4460606,4466047,4471575,4477022,4482514,4487991,4493463,4498996,4504535,4510062,4515582,4521040,4526576,4532043,4537551,4543006,4548526,4554051,4559544,4565039,4570576,4576018,4581510,4586928,4592508,4597955,4603527,4608972,4614444,4619984,4625476,4630913,4636426,4641948,4647416,4652931,4658438,4663931,4669382,4674878,4680315,4685896,4691370,4696907,4702361,4707853,4713384,4718907,4724409,4730004,4735525,4740992,4746465,4752027,4757470,4762951,4768393,4773922,4779430,4784949,4790384,4795812,4801310,4806760,4812305,4817816,4823303,4828831,4834317,4839761,4845183,4850683,4856110,4861617,4867093,4872513,4878005,4883558,4889139,4894521,4899985,4905417,4910914,4916472,4921878,4927326,4932826,4938246,4943731,4949180,4954637,4960077,4965591,4971111,4976569,4982049,4987530,4993012,4998470,5003979,5009407,5014862,5020351,5025823,5031315,5036777,5042265,5047761,5053180,5058696,5064123,5069614,5075035,5080463,5085953,5091415,5096846,5102346,5107832,5113355,5118791,5124356,5129773,5135232,5140593,5146076,5151557,5157086,5162565,5167986,5173502,5178996,5184377,5189833,5195242,5200653,5206040,5211514,5216954,5222465,5227980,5233446,5238910,5244409,5249827,5255274,5260749,5266190,5271659,5277103,5282580,5288120,5293544,5298991,5304404,5309926,5315370,5320738,5326237,5331696,5337154,5342570,5348001,5353469,5358873,5364374,5369836,5375312,5380681,5386095,5391573,5396981,5402486,5407914,5413340,5418747,5424169,5429670,5435104,5440645,5446042,5451511,5456922,5462365,5467823,5473280,5478704,5484246,5489749,5495144,5500596,5506042,5511482,5516967,5522414,5527834,5533229,5538712,5544201,5549568,5555003,5560413,5565874,5571310,5576734,5582247,5587668,5593068,5598565,5604003,5609349,5614798,5620231,5625732,5631229,5636652,5642089,5647525,5652996,5658353,5663763,5669215,5674668,5680084,5685585,5691004,5696344,5701777,5707123,5712622,5718013,5723380,5728833,5734258,5739704,5745162,5750539,5756001,5761455};
ll mul(ll a,ll b,ll mod){//高精度
    a%=mod;
    b%=mod;
    ll c=(long double)a*b/mod;
    ll ans=a*b-c*mod;
    return (ans%mod+mod)%mod;
}
ll pow_mod(ll x,ll n,ll mod){//快速冪
    ll res=1;
    while(n){
        if(n&1)
        res=mul(res,x,mod);
        x=mul(x,x,mod);
        n>>=1;
    }
    return (res+mod)%mod;
}
bool Miller_Rabbin(ll a,ll n){
    ll s=n-1,r=0;
    while((s&1)==0){
        s>>=1;r++;
    }
    ll k=pow_mod(a,s,n);
    if(k==1)return true;
    for(int i=0;i<r;i++,k=k*k%n){
        if(k==n-1)return true;
    }
    return false;
}
bool isprime(ll n){
    if(n==1||n==0)return false;
    ll times=7;
    ll prime[100]={2,3,5,7,11,233,331};
    for(int i=0;i<times;i++){
        if(n==prime[i])return true;
        if(Miller_Rabbin(prime[i],n)==false)return false;
    }
    return true;
}
int main(){
    
/* 分塊打表程式碼
    ll cnt=0;
    //freopen("C:\\test.txt","w",stdout);
    printf("0,");
    for(ll i=1;i<=1e8;i+=100000){
        for(ll j=i;j<=i+100000-1;j++){
            if(isprime(j)){
                cnt++;
            }
        }
        printf("%lld,",cnt);
    }
*/
    ll n;
    while(scanf("%lld",&n)&&n!=0){
        ll f=n/100000;
        ll cnt=0;
        for(int i=100000*f+1;i<=n;i++){
            if(isprime(i)){
                cnt++;
            }
        }
        printf("%lld\n",cnt+a[f]);
    }
	return 0;
}