【数论】Prime Time UVA

题意:验证1~10000 的数 n^n+n+41 中素数的个数。每个询问给出a,b  求区间[a,b]中质数出现的比例,保留两位

题解:质数会爆到1e8 所以用miller robin ,

另外一个优化是预处理

一个坑是四舍五入卡精度。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<ctime>
using namespace std;
typedef long long ll;
const int MAXN = 10000000 + 10000 + 42;
const int maxn = MAXN;
#define rep(i,t,n)  for(int i =(t);i<=(n);++i)
#define per(i,n,t)  for(int i =(n);i>=(t);--i)
#define mmm(a,b) memset(a,b,sizeof(a))
int phi[MAXN], prime[MAXN];
struct Miller_Rabin
{
    int prime[5] = { 2,3,5,233,331 };
    ll qmul(ll x, ll y, ll mod) {
        ll ans = (x*y - (ll)((long double)x / mod * y + 1e-3)*mod);
        ans = (ans%mod + mod) % mod;
        return ans;
    }
    ll qpow(ll x, ll n, ll mod) {
        ll ans = 1;
        while (n) {
            if (n & 1) ans = qmul(ans, x, mod);
            x = qmul(x, x, mod);
            n >>= 1;
        }
        return ans;
    }
    bool isprime_std(ll p) {
        if (p < 2) return 0;
        if (p != 2 && p % 2 == 0) return 0;
        ll s = p - 1;
        while (!(s & 1)) s >>= 1;
        for (int i = 0; i < 5; ++i) {
            if (p == prime[i]) return 1;
            ll t = s, m = qpow(prime[i], s, p);
            while (t != p - 1 && m != 1 && m != p - 1) {
                m = qmul(m, m, p);
                t <<= 1;
            }
            if (m != p - 1 && !(t & 1)) return 0;
        }
        return 1;
    }
    bool isprime(ll p) {
        if (p<2 || (p != 2 && p % 2 == 0)) return false;
        for (int i = 0; i < 5; ++i)
        {
            if (p == prime[i]) return true;
            ll t = qpow(prime[i], p - 1, p);
            if (t != 1) return false;
        }
        return true;
    }
}mr;
int tot;
void get_phi()
{
    phi[1] = 1;
    for (int i = 2; i <= MAXN - 9; i++) {
        if (!phi[i]) {
            phi[i] = i - 1;
            prime[++tot] = i;
        }
        for (int j = 1; j <= tot && 1LL * i*prime[j] <= MAXN - 9; j++) {
            if (i%prime[j]) phi[i*prime[j]] = phi[i] * (prime[j] - 1);
            else {
                phi[i*prime[j]] = phi[i] * prime[j];
                break;
            }
        }
    }
}
int isntp[maxn];
void sieve(int n) {
    int m = (int)sqrt(n + 0.5);
    mmm(isntp, 0);
    rep(i, 2, m)if (!isntp[i])for (int j = i * i; j <= n; j += i)isntp[j] = 1;

}
int ans[maxn];
int s[maxn];
int smain();
//#define ONLINE_JUDGE
int main() {

    //ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    FILE *myfile;
    myfile = freopen("C:\Users\acm-14\Desktop\test\b.in", "r", stdin);
    if (myfile == NULL)
        fprintf(stdout, "error on input freopen
");
    FILE *outfile;
    outfile = freopen("C:\Users\acm-14\Desktop\test\out.txt", "w", stdout);
    if (outfile == NULL)
        fprintf(stdout, "error on output freopen
");
    long _begin_time = clock();
#endif
    smain();
#ifndef ONLINE_JUDGE
    long _end_time = clock();
    printf("time = %ld ms.", _end_time - _begin_time);
#endif
    return 0;
}
int smain()
{

    int t;
    int a, b;

    s[0] = 1;
    rep(i, 1, 1e4) {
        if (mr.isprime_std(i * i + i + 41))s[i] = s[i - 1] + 1;
        else s[i] = s[i - 1];
    }
    while (cin >> a >> b)
    {
        int cnt = 0;
        /*rep(i, a, b) {
        if (i * i + i + 41 < 1e7) {
        if (isntp[i * i + i + 41] == 0)cnt++;
        else if(mr.isprime(i * i + i + 41))cnt++;
        }
        }*/
        cnt = s[b];
        if (a != 0)cnt -= s[a - 1];
        double ans = (double)cnt / (double)(b - a + 1) * 10000;
        ans = (double)((int)(ans + 0.50000001));
        
        printf("%.2lf
", ans/100);
    }
    //cin >> t;
    return 0;
}
/*
0 39
0 40
39 40
*/
成功的路并不拥挤,因为大部分人都在颓(笑)
原文地址:https://www.cnblogs.com/SuuT/p/9678868.html