hdu 3823 线性筛法

筛出足够多的素数然后存起来查找即可。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6
 7 typedef long long ll;
 8 const int N = 20000001;
 9 const int M = 1500000;
10 const int K = 150;
11 const int L = 200000;
12 bool visit[N];
13 int prime[M];
14 int ss[K][L];
15 int pm[K];
16 int pn;
17
18 void better_get_prime()
19 {
20     pn = 0;
21     memset( visit, 0, sizeof(visit) );
22     visit[0] = visit[1] = 1;
23     for ( int i = 2; i < N; i++ )
24     {
25         if ( !visit[i] ) prime[pn++] = i;
26         for ( int j = 0; j < pn && ( ll ) i * prime[j] < N; j++ )
27         {
28             visit[i * prime[j]] = 1;
29             if ( i % prime[j] == 0 ) break;
30         }
31     }
32     memset( pm, 0, sizeof(pm) );
33     for ( int i = 0; i < pn - 1; i++ )
34     {
35         int d = prime[i + 1] - prime[i];
36         if ( d < K )
37         {
38             ss[d][pm[d]++] = prime[i];
39         }
40     }
41 }
42
43 int main ()
44 {
45     better_get_prime();
46     int t;
47     scanf("%d", &t);
48     for ( int _case = 1; _case <= t; _case++ )
49     {
50         int x, y;
51         scanf("%d%d", &x, &y);
52         if ( x > y ) swap( x, y );
53         int d = y - x, ans = -1;
54         for ( int i = 0; i < pm[d]; i++ )
55         {
56             if ( ss[d][i] >= x )
57             {
58                 ans = ss[d][i] - x;
59                 break;
60             }
61         }
62         printf("Case %d: %d\n", _case, ans);
63
64     }
65     return 0;
66 }
时间: 2024-10-11 17:48:19

hdu 3823 线性筛法的相关文章

欧拉线性筛法求素数(顺便实现欧拉函数的求值)

我们先来看一下最经典的埃拉特斯特尼筛法.时间复杂度为O(n loglog n) int ans[MAXN]; void Prime(int n) { int cnt=0; memset(prime,1,sizeof(prime)); prime[0]=prime[1]=0; for(int i=2;i<n;i++) { if(vis[i]) { ans[cnt++]=i;//保存素数 for(int j=i*i;j<n;j+=i)//i*i开始进行了稍微的优化 prime[j]=0;//不是素

线性筛法

关于线性筛法 线性是指O(n)内筛掉所有合数,还有一种方法叫埃氏筛法,我先证明埃氏筛法效率低,也就是会有重复. 证明如下: 埃氏筛法的原理是找到一个素数后,它的1~n倍就会被筛掉,任何一个合数都可以被拆成一个质数*合数的形式,我们对每一个质数对应的可能的(合)数都枚举了,这就保证了所有可能的合数都被筛掉了.为什么不是最优呢?问题出在那个质数上,对于一个合数m,m=h*P,P是质数且P>m的最小质因数,那么m也可以表示为m=H*p,(H是个比h大的合数,p是m的最小质因数),这样我们在枚举p的倍数

线性筛法求素数

为什么称为线性,因为普通的筛法重复了好多次,冗余,而线性筛法避免了冗余. ①如果 i 都是是素数的话,那简单,一个大的素数 i 乘以不大于 i 的素数,这样筛除的数跟之前的是不会重复的.筛出的数都是 N=p1*p2的形式, p1,p2之间不相等 ②如果 i 是合数,此时 i 可以表示成递增素数相乘 i=p1*p2*...*pn, pi都是素数(2<=i<=n),  pi<=pj  ( i<=j )p1是最小的系数. 根据“关键处2”的定义,当p1==prime[j] 的时候,筛除就

数论 - 线性筛法与积性函数

首先以求1000000以内的素数为例来探讨筛法 Eratosthenes筛法(埃拉托斯特尼筛法) 时间复杂度:O(N*loglogN) 空间复杂度:O(N) 代码: #include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <queue> #include <stack> #include <bit

POJ-2689 Prime Distance(线性筛法)

Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17021   Accepted: 4536 Description The branch of mathematics called number theory is about properties of numbers. One of the areas that has captured the interest of number th

读贾志鹏《线性筛法与积性函数》笔记

1.欧拉筛法在线性时间内求素数以及欧拉函数 代码: 1 procedure get; 2 var i,j,k:longint; 3 begin 4 tot:=0; 5 fillchar(check,sizeof(check),false); 6 for i:=2 to n do 7 begin 8 if not(check[i]) then 9 begin 10 inc(tot); 11 p[tot]:=i; 12 fai[i]:=i-1; 13 end; 14 for j:=1 to tot

一般筛法求素数+快速线性筛法求素数

素数总是一个比较常涉及到的内容,掌握求素数的方法是一项基本功. 基本原则就是题目如果只需要判断少量数字是否为素数,直接枚举因子2 ..N^(0.5) ,看看能否整除N. 如果需要判断的次数较多,则先用下面介绍的办法预处理. 一般的线性筛法 首先先介绍一般的线性筛法求素数 void make_prime() { memset(prime, 1, sizeof(prime)); prime[0]=false; prime[1]=false; int N=31700; for (int i=2; i<

POJ 1007 Difference Between Primes(线性筛法求N以内的素数表)

Difference Between Primes Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description All you know Goldbach conjecture.That is to say, Every even integer greater than 2 can be expressed as the sum of two primes. Today, sk

线性筛法(欧拉筛法)求素数

写$\text{O}\left( n \log{\log{n}}\right)$的筛法很长时间了,我却从来没想过它的优化.偶然间看到线性筛法,心想大约是不错的优化,于是便爬去学习下. 首先,$\text{O}\left( n \log{\log{n}}\right)$的筛法肯定要比$\text{O}\left( n\right)$的慢,虽然在现在的机子上不明显.还是不要将$\text{O}\left( n \log{\log{n}}\right)$比较靠谱.但是线性筛法有着它自己的用途.