hnu Dirichlet's Theorem

  1 /*
  2 求ax+b  x属于区间[L,R];范围内素数的个数。
  3 a*R+b<=10^12 ;  R-L+1<=10^6
  4
  5 枚举,超时。
  6 1.如果GCD(a,b)>1 那么a+b 2*a+b ..都会是合数。此时只有判断b是否为素数。
  7
  8 2.如果GCD(a,b)=1 那么就可以列式子
  9   ax+b %p = 0  其中p为素数。 如果满足,那么ax+b就是合数。
 10   筛选整个区间即可。
 11
 12 由于最大的数字是10^12,只能被sqrt(10^12)的素数整除,所以筛选10^6内的素数。
 13 由于区间L,R 10^6,开一个bool hash[ ]。
 14
 15 ax+b % py = 0  ===>  ax+py = -b;
 16
 17 根据扩展欧几里得求出 最小的x,此时的x可以为0.  while(x<0) x+p;
 18
 19 求出最小的x,关键还要求出第一个满足在区间[ L ,R ]里的数字。
 20
 21 temp = L%p;
 22 x = x - temp;
 23
 24 while(a*(L+x)+b<=p) { //关于此处等号,是一个问题 既然a*x+b 是合数,怎么会=p,加了也不会错。
 25  x = x + p;
 26 }
 27
 28 这样的L+x就是区间[L ,R]里的第一个满足的数字。
 29 而且x可以为0,刚好用hash的时候,直接对x进行哈希。
 30
 31 while(x<(R-L+1)){//不能等于,从0 --R-L  有 R-L+1个了。
 32 hash[x] = false;
 33 x = x+p;
 34 }
 35
 36 3.最后求出结果。扫一遍哈希。
 37
 38
 39 需要注意的是,由于a*x+b <=2的情况,所以对x==0 || x<=1 进行特判。
 40 */
 41 #include<iostream>
 42 #include<stdio.h>
 43 #include<cstring>
 44 #include<cstdlib>
 45 #include<math.h>
 46 using namespace std;
 47 typedef long long LL;
 48
 49 const int maxn = 1e6+1;
 50 int prime[maxn],len = 0;
 51 bool s [maxn];
 52 bool hash1[maxn];
 53 void init()
 54 {
 55     int i,j;
 56     memset(s,true,sizeof(s));
 57     for(i=2;i<maxn;i++)
 58     {
 59         if(s[i]==false) continue;
 60         prime[++len] = i;
 61         for(j=i*2;j<maxn;j=j+i)
 62             s[j]=false;
 63     }
 64     s[0] = s[1] = false;
 65 }
 66 bool isprime(LL n)
 67 {
 68     LL i,ans;
 69     if(n<maxn) return s[n];
 70     ans = (LL)sqrt(n*1.0);
 71
 72     for(i=1; i<=len && prime[i]<=ans; i++)
 73     {
 74         if(n%prime[i]==0) return false;
 75     }
 76     return true;
 77 }
 78 LL Ex_GCD(LL a,LL b,LL &x,LL& y)
 79 {
 80     if(b==0)
 81     {
 82         x=1;
 83         y=0;
 84         return a;
 85     }
 86     LL g=Ex_GCD(b,a%b,x,y);
 87     LL hxl=x-(a/b)*y;
 88     x=y;
 89     y=hxl;
 90     return g;
 91 }
 92 int main()
 93 {
 94     LL a,b,L,U,x,y;
 95     LL i,p;
 96     int t = 0;
 97     init();
 98     while(scanf("%I64d",&a)>0)
 99     {
100         if(a==0)break;
101         scanf("%I64d%I64d%I64d",&b,&L,&U);
102         LL g = Ex_GCD(a,b,x,y);
103         if(g>1)
104         {
105             if(L==0 && isprime(b))
106                 printf("Case %d: 1\n",++t);
107             else printf("Case %d: 0\n",++t);
108         }
109         else if(g==1)/** gcd(a,b) == 1   **/
110         {
111             memset(hash1,true,sizeof(hash1));
112             if(L==0)
113                 hash1[0] = isprime(b);
114             if(L<=1)
115                 hash1[1-L] = isprime(a+b);
116             LL length = U-L+1;
117             LL MAX = a*U+b;
118             for(i=1; i<=len; i++)
119             {
120                 p = prime[i];
121                 if(a%p==0)continue;
122                 if(p*p>MAX)break;;
123
124                 g = Ex_GCD(a,p,x,y);// ax+py = -b;
125                 x = (x*-b) % p;
126                 while(x<0) x=x+p;
127
128                 LL temp = L%p;
129                 x = x - temp;
130                 while(x<0) x=x+p;
131
132                 while(a*(x+L)+b<=p)
133                 {
134                     x = x+p;
135                 }
136                 while(x<length)
137                 {
138                     hash1[x]=false;
139                     x=x+p;
140                 }
141             }
142             LL hxl = 0;
143             for(i=0; i<length; i++) if(hash1[i]==true) hxl++;
144             printf("Case %d: %I64d\n",++t,hxl);
145         }
146     }
147     return 0;
148 }

hnu Dirichlet's Theorem

时间: 2024-10-09 08:17:03

hnu Dirichlet's Theorem的相关文章

poj 3006 Dirichlet&#39;s Theorem on Arithmetic Progressions

Description If a and d are relatively prime positive integers, the arithmetic sequence beginning with a and increasing by d, i.e., a, a + d, a + 2d, a + 3d, a + 4d, ..., contains infinitely many prime numbers. This fact is known as Dirichlet's Theore

(素数求解)I - Dirichlet&#39;s Theorem on Arithmetic Progressions(1.5.5)

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description If a and d are relatively prime positive integers, the arithmetic sequence beginning with a and increasing by d, i.e., a, a + d, a + 2d, a + 3d, a 

POJ 3006 Dirichlet&#39;s Theorem on Arithmetic Progressions 素数 难度:0

http://poj.org/problem?id=3006 #include <cstdio> using namespace std; bool pm[1000002]; bool usd[1000002]; bool judge(int x) { if(usd[x])return pm[x]; usd[x] = true; if(x == 2) return pm[x] = true; if(((x & 1) == 0) || (x < 2))return pm[x] =

poj3006 Dirichlet&#39;s Theorem on Arithmetic Progressions

Dirichlet's Theorem on Arithmetic Progressions Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16333   Accepted: 8205 Description If a and d are relatively prime positive integers, the arithmetic sequence beginning with a and increasing

【POJ3006】Dirichlet&#39;s Theorem on Arithmetic Progressions(素数筛法)

简单的暴力筛法就可. 1 #include <iostream> 2 #include <cstring> 3 #include <cmath> 4 #include <cctype> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <numeric> 9 using namespace std; 10 11 co

POJ 3006 Dirichlet&#39;s Theorem on Arithmetic Progressions 快筛质数

题目大意:给出一个等差数列,问这个等差数列的第n个素数是什么. 思路:这题主要考如何筛素数,线性筛.详见代码. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 1000010 using namespace std; int prime[MAX],primes; bool notp[MAX]; int a,d,n;

判断素数——Dirichlet&#39;s Theorem on Arithmetic Progressions

Description If a and d are relatively prime positive integers, the arithmetic sequence beginning with a and increasing by d, i.e., a, a + d, a + 2d, a + 3d, a + 4d, ..., contains infinitely many prime numbers. This fact is known as Dirichlet's Theore

Dirichlet&#39;s Theorem on Arithmetic Progressions POJ - 3006 线性欧拉筛

题意 给出a d n    给出数列 a,a+d,a+2d,a+3d......a+kd 问第n个数是几 保证答案不溢出 直接线性筛模拟即可 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 bool Is_Primes[1000005]; 5 int Primes[1000005]; 6 int A[1000005]; 7 int cnt; 8 void Prime(int n){ 9 cnt=0; 1

POJ - 3006 - Dirichlet&#39;s Theorem on Arithmetic Progressions = 水题

http://poj.org/problem?id=3006 给一个等差数列,求其中的第n个质数,答案保证不超过1e6.n还特别小?!!! 埃筛之后暴力. #include<algorithm> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<map> #include<set> #include<stack