zoukankan      html  css  js  c++  java
  • 《hdu6889》

    这题就是Min25筛素数和。

    但是一直TLE,然后调试了很久,发现如果在计算素数和的过程中取模,就会导致超时。(离谱)

    给出解决思路:n = 1e11,里面的素数和不会爆longlong,所以对在求解素数和的时候,不需要去取模,最后对答案取模就行。

    至于求解素数和:可以看成求解f[i] = i的质数部分和,然后上Min25筛即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<LL,int> pii;
    const int N = 1e6+5;
    const int M = 1e6+5;
    //const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e18
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    
    LL sum1[N],prime[N],id1[N],id2[N],g1[N],g2[N],w[N],Mod;
    LL n,Sqr,tot = 0,m = 0;
    bool flag[N];
    inline LL f1(LL x)//F[i] = i的前缀和
    {
        return (x + 1) * x / 2 - 1;
    }
    inline LL getid(LL x)//找到x的离散化对应位置
    {
        if(x <= Sqr) return id1[x];
        else return id2[n/x];
    }
    inline void init()
    {
        Sqr = sqrt(n + 0.5);
        m = 0,tot = 0;
        for(int i = 2;i <= Sqr;++i)
        {
            if(!flag[i])
            {
                prime[++tot] = i;
                sum1[tot] = (sum1[tot-1]+i) % Mod;
            }
            for(int j = 1;j <= tot && prime[j]*i <= Sqr;++j)
            {
                flag[i*prime[j]] = 1;
                if(i%prime[j] == 0) break;
            }
        }
        for(LL L = 1,r;L <= n;L = r+1)//预处理g(n,0)
        {
            r = (n/(n/L)),w[++m] = (n/L);
            if(w[m] <= Sqr) id1[w[m]] = m;
            else id2[n / w[m]] = m;
            g1[m] = f1(w[m]);
        }
        for(int i = 1;i <= tot;++i){//预处理到sqrt(n),即tot即可
            for(int j = 1;j <= m && prime[i] * prime[i] <= w[j];++j){
                g1[j] = g1[j] - prime[i] * (g1[getid(w[j] / prime[i])] - sum1[i-1]);
            }
        }
    }
    int main()
    {
        int ca;ca = read();
        while(ca--)
        {
            n = read(),Mod = read();
            if(n == 1) printf("0
    ");
            else if(n == 2) printf("%lld
    ",6 % Mod);
            else
            {
                n++;
                init();
                LL ans =  g1[getid(n)]-2;
                n %= Mod;
                LL ma = 1LL * (n+3) * (n-2) / 2 % Mod;
                ma = (ma + ans) % Mod;
                printf("%lld
    ",ma);
            }
        }
        //system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    假期进度报告2
    假期进度报告1
    JavaScript下判断元素是否存在
    浪潮之巅阅读笔记06
    浪潮之巅阅读笔记05
    浪潮之巅阅读笔记04
    【C语言】C语言简介
    iOS网络监测方法
    iOS常用手势识别器
    【CoreData】 简单地使用
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13729511.html
Copyright © 2011-2022 走看看