zoukankan      html  css  js  c++  java
  • 【HDU】2138 How many prime numbers

    http://acm.hdu.edu.cn/showproblem.php?pid=2138

    题意:给n个数判断有几个素数。(每个数<=2^32)

    #include <cstdio>
    using namespace std;
    typedef long long ll;
    ll ipow(ll a, ll b, ll m) { ll x=1; for(; b; b>>=1, (a*=a)%=m) if(b&1) (x*=a)%=m; return x; }
    ll rand(ll a, ll b) {
    	static const ll M=1e9+7, g=154865266;
    	static ll now=1283901ll;
    	return a+((now*=g)%=M)%(b-a+1);
    }
    bool check(ll x) {
    	if(x==2 || x==3 || x==5 || x==7 || x==11 || x==13) return 1;
    	if(x<2 || (x&1)==0 || (x%3)==0 || (x%5)==0 || (x%7)==0 || (x%11)==0 || (x%13)==0) return 0;
    	int cnt=0;
    	ll d=x-1; while((d&1)==0) d>>=1, ++cnt;
    	for(int T=1; T<=50; ++T) {
    		int a=rand(2, x-1);
    		ll t=ipow(a, d, x), pre;
    		for(int i=1; i<=cnt; ++i) { pre=t; (t*=t)%=x; if(t==1 && pre!=1 && pre!=x-1) return 0; }
    		if(t!=1) return 0;
    	}
    	return 1;
    }
    int main() {
    	int n;
    	while(~scanf("%d", &n)) {
    		int ans=0;
    		for(int i=1; i<=n; ++i) { int a; scanf("%d", &a); if(check(a)) ++ans; }
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    

      

    学习了素数检测= =Miller-Rabin...复杂度$O(k log^3 n)$,k是选的$a$的个数

    其实基于两个定理:费马小定理和二次探测...

    首先如果$n$是奇素数,那么显然对于所有的$1 le a < n$,都有$a^{(n-1)} equiv 1 pmod{n}$,那么我们马上可以得到一个暴力算法= =(比枚举约数还慢系列= =

    然后用那啥二次探测定理然后随机选一些$a$然后一定概率来检测$n$= =(听说单次检测是$3/4$的概率= =那么多次检测成功率很高= =$n$次的能检测出来的概率就是$1 - left( frac{1}{4} ight) ^n$

    二项探测就是指如果$n$是素数,则$x^2 equiv 1 pmod{n}, 0<=x<n$的只有就是$x = 1 或 x = n-1$

    证明:容易得到$p | (x+1)(x-1)$。而由于$p$是质数,所以$(x+1)$和$(x-1)$中至少一个被$p$整除。那么容易得到$x = pm 1$,即$x equiv 1 或 x equiv n-1$

    然后我们就将$n-1$分解成$2^sd$其中$d$为奇数。这样我们从$a^d$开始向上算,每一次平方一次,如果等于$1$而上一次却不等于$pm 1$,那么为合数。

  • 相关阅读:
    get与post区别
    移动应用专项测试的思路和方法
    一个完整的http请求响应过程
    Linux基础
    浏览器输入url按回车背后经历了哪些?
    三大浏览器(火狐-谷歌-IE浏览器)驱动版本下载
    boost-序列化
    HTTP 2.0
    http首部字段
    与http协作的web服务器
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4353427.html
Copyright © 2011-2022 走看看