zoukankan      html  css  js  c++  java
  • 【数论】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
    */
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    CLR via C#
    一些写英文简历的词汇
    组合与组合数
    A lowlevel Look at the ASP.NET Architecture
    \r与\n的区别,\r\n与\n或\r的区别(C语言/C#)
    Canvas lineWidth 属性 【每日一段代码18】
    程序员三大世界观 如何看待HTML5
    Canvas运用样式与颜色fillStyle【每日一段代码15】
    Canvas绘制路径:贝塞尔曲线【每日一段代码12】
    Canvas绘制弧形【每日一段代码10】
  • 原文地址:https://www.cnblogs.com/SuuT/p/9678868.html
Copyright © 2011-2022 走看看