快速幂乘法+素数测试法

也没怎么学习新的知识,稍微写一点。下面是快速幂乘法,pow,以前只知道pow的写法,不知道快速幂取余的写法,然后这里补上(真的很重要),同时下面的方法是素数测试法,就是Miller-Rabin质数测试,一般的方法是sqrt(n)的复杂度进行判断,但是miller-rabin方法更跨一些,好像是s*(logk)^3的复杂度。涉及到费马小定理,fermat测试,二次探测定理。然后学习下质数筛选法,叫eular筛选法。这几天接触到知识点有:grundy theory(game theory,sg函数,异或,nim),知道有这个知识点,但是遇到具体的问题,还是分析不出来;扩展欧几里得算法,就是辗转相除法,欧几里得算法求出来2个因数,用来求解不定方程;区间减法的性质还是要熟练使用,几何的知识点,判断点在直线的哪一侧,判断点在凸多边形的内部还是外部,椭圆的性质,以及搜索满足条件的点的时候,在所有的空间上进行二分,如果无法求得邻近的点,一般用三分(ternary search),之所以能够这样,是要先把题目转化成满足这些性质的函数,然后在此基础上进行二分。如何形式化的描述一个问题,非常重要。啰嗦了这么多,也不知道想写些什么!-0-

补充:以前见过一个求任意区间素数的方法,但是忘了,这里补上。

基本思路:因为b以内合数的最小质因数一定不超过sqrt(b),如果有sqrt(b)以内的素数表的话,就可以把筛选法用在[a,b)上了,先分别做好[2,sqrt(b))的表和[a,b)的表,然后从[2,sqrt(b))的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是区间[a,b)内的素数了。

看这个链接就行:http://www.cnblogs.com/nowandforever/p/4515612.html

 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i)
 4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl
 5 typedef long long ll;
 6 typedef long long LL;
 7 using namespace std;
 8 typedef pair<int, int> pii;
 9 const int maxn = 1e3 + 10;
10 const ll inf = 1e18 + 10;
11 #define RAND_MAX inf
12 ll pow(ll x, ll n, ll mod) {
13     ll res = 1 % mod;
14     while(n) {
15         if(n & 1) res = (res * x) % mod;
16         x = (x * x) % mod;
17         n >>= 1;
18     }
19     return res;
20 }
21 LL mod_mul(LL a, LL b, LL n) {
22     LL res = 0;
23     while (b) {
24         if (b & 1)    res = (res + a) % n;
25         a = (a + a) % n;
26         b >>= 1;
27     }
28     return res;
29 }
30 
31 LL mod_exp(LL a, LL b, LL n) {
32     LL res = 1;
33     while (b) {
34         if (b & 1)    res = mod_mul(res, a, n);
35         a = mod_mul(a, a, n);
36         b >>= 1;
37     }
38     return res;
39 }
40 bool work(ll x) {
41     if(x <= 5) {
42         if(x == 2 || x == 3 || x == 5) return 1;
43         return 0;
44     }
45     if((x & 1) == 0) return 0;
46     ll u = x - 1;
47     while(u % 2 == 0) u /= 2;
48     //set<ll> se;
49     int cnt = 10;
50     srand(time(0));
51     while(cnt--) {
52         ll a = 2 + rand() % (x - 3);
53         ll p = u;
54         ll t = mod_exp(a, p, x);
55         while(p < x) {
56             ll y = mod_mul(t, t, x);
57             if((y == 1 && (t != 1 && t != x - 1)))  {
58                 return 0;
59             }
60             t = y;
61             p *= 2;
62         }
63         if(t != 1)
64             return 0;
65     }
66     return 1;
67 }
68 void solve() {
69     int n;
70     ll x;
71     cin >> n;
72     while(n--) {
73         cin >> x;
74         if(work(x)) cout << "Yes" << endl;
75         else cout << "No" << endl;
76     }
77 }
78 int main() {
79     freopen("test.in", "r", stdin);
80     //freopen("test.out", "w", stdout);
81     solve();
82     return 0;
83 }
 1 #include<bits/stdc++.h>
 2 #define pb push_back
 3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i)
 4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl
 5 typedef long long ll;
 6 using namespace std;
 7 typedef pair<int, int> pii;
 8 const int maxn = 1e6 + 10;
 9 bool a[maxn];
10 int p[maxn];
11 int cnt;
12 void solve() {
13     int n;
14     cin >> n;
15     int res = 0;
16     for (int i = 2; i <= n; i++) {
17         if(a[i]) continue;
18         res++;
19         for (ll j = 1ll * i * i; j <= n; j += i) {
20             a[j] = 1;
21         }
22     }
23     cout << res << endl;
24 }
25 void solve1() {
26     memset(a, -1, sizeof a);
27     int n; cin >> n;
28     for (int i = 2; i <= n; i++) {
29         if(a[i]) {
30             p[cnt++] = i;
31             //cout << i << endl;
32         }
33         for (int j = 0; j < cnt; j++) {
34             if(1ll * i * p[j] > n) break;
35             a[i * p[j]] = 0;
36             if(i % p[j] == 0) break;
37         }
38     }
39     cout << cnt << endl;
40 }
41 int main() {
42     //freopen("test.in", "r", stdin);
43     //freopen("test.out", "w", stdout);
44     solve1();
45     return 0;
46 }

 

转载于:https://www.cnblogs.com/y119777/p/6056950.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值