题意:验证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\n"); FILE *outfile; outfile = freopen("C:\\Users\\acm-14\\Desktop\\test\\out.txt", "w", stdout); if (outfile == NULL) fprintf(stdout, "error on output freopen\n"); 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\n", ans/100); } //cin >> t; return 0; } /* 0 39 0 40 39 40 */