zoukankan      html  css  js  c++  java
  • [LOJ#6053]简单的函数 题解

    最近在搞min_25筛,就写几道筛法题吧

    模板题,直接套板子就好了

    //waz
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(), (x).end()
    #define SZ(x) ((int)((x).size()))
    
    typedef pair<int, int> PII;
    typedef vector<int> VI;
    typedef long long int64;
    typedef unsigned int uint;
    typedef unsigned long long uint64;
    
    #define gi(x) ((x) = F())
    #define gii(x, y) (gi(x), gi(y))
    #define giii(x, y, z) (gii(x, y), gi(z))
    
    int F()
    {
        char ch;
        int x, a;
        while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-');
        if (ch == '-') ch = getchar(), a = -1;
        else a = 1;
        x = ch - '0';
        while (ch = getchar(), ch >= '0' && ch <= '9')
            x = (x << 1) + (x << 3) + ch - '0';
        return a * x;
    }
    
    const int mod = 1e9 + 7;
    
    int inc(int a, int b) { a += b; return a >= mod ? a - mod : a; }
    
    int dec(int a, int b) { a -= b; return a < 0 ? a + mod : a; }
    
    int fpow(int a, int x)
    {
        int ret = 1;
        for (; x; x >>= 1)
        {
            if (x & 1) ret = 1LL * ret * a % mod;
            a = 1LL * a * a % mod;
        }
        return ret;
    }
    
    const int N = 1e5 + 10;
    
    int64 n;
    
    int p[N], pt, sump[N], sumf[N];
    
    bool fg[N];
    
    int sqrtn;
    
    namespace work1
    { 
        int f1[N << 1], f2[N << 1]; 
        int id1[N], id2[N], idt;
        int64 num[N << 1];
        int id(int64 x) { if (x <= sqrtn) return id1[x]; else return id2[n / x]; }
        void solve()
        {
            idt = 0;
            for (int64 i = 1, j; i <= n; i = j + 1)
            {
                int64 t = n / i;
                j = n / t;
                if (t <= sqrtn) id1[t] = ++idt;
                else id2[n / t] = ++idt;
                num[idt] = t;
                int64 c = t % mod;
                f1[idt] = (c * (c + 1) / 2 + mod - 1) % mod;
                f2[idt] = c - 1;
            }
            for (int j = 1; j <= pt; ++j)
            {
                int64 end = 1LL * p[j] * p[j];
                for (int k = 1; num[k] >= end; ++k)
                {
                    int i = id(num[k] / p[j]);
                    f1[k] = dec(f1[k], 1LL * dec(f1[i], sump[j - 1]) * p[j] % mod);
                    f2[k] = dec(f2[k], 1LL * dec(f2[i], j - 1));
                }
            }
        }
        int query(int64 x) { return inc(dec(f1[id(x)], f2[id(x)]), 2 * (x >= 2)); }
    }
    
    namespace work2
    {
        int g[N << 1];
        int id1[N], id2[N], idt;
        int64 num[N << 1];
        int id(int64 x) { if (x <= sqrtn) return id1[x]; else return id2[n / x]; }
        int solve()
        {
            for (int64 i = 1, j; i <= n; i = j + 1)
            {
                int64 t = n / i;
                j = n / t;
                if (t <= sqrtn) id1[t] = ++idt;
                else id2[n / t] = ++idt;
                num[idt] = t;
                g[idt] = work1::query(t);
            }
            for (int j = pt; j; --j)
            {
                for (int k = 1; num[k] >= 1LL * p[j] * p[j]; ++k)
                {
                    int i = 1;
                    for (int64 m = p[j]; m * p[j] <= num[k]; ++i, m *= p[j])
                    {
                        g[k] = inc(g[k], 1LL * dec(g[id(num[k] / m)], sumf[j]) * (p[j] ^ i) % mod);
                        g[k] = inc(g[k], p[j] ^ (i + 1));
                    }
                }
            }
            return inc(g[id(n)], 1);
        }
    }
    
    int main()
    {
        cin >> n;
        sqrtn = sqrt(n);
        for (int i = 2; i <= sqrtn; ++i)
        {
            if (!fg[i])
            {
                p[++pt] = i;
            }
            for (int j = 1; j <= pt && p[j] * i <= sqrtn; ++j)
            {
                fg[p[j] * i] = 1;
                if (i % p[j] == 0) break;
            }
        }
        for (int i = 1; i <= pt; ++i) sump[i] = inc(sump[i - 1], p[i]), sumf[i] = inc(sumf[i - 1], p[i] ^ 1);
        work1::solve();
        //cerr << work1::query(n) << endl;
        cout << work2::solve() << endl;
    } 
  • 相关阅读:
    跳板机操作
    常用进制之间的转换
    vim加脚本注释和文本加密
    LAMP框架
    wiki团队协作软件Confluence
    NFS网络文件系统
    ORACLE-12C-RAC INSTALL
    通过DB_LINK按照分区表抽取数据
    Oracle Rac crs无法启动
    删除undotbs后,数据库无法启动
  • 原文地址:https://www.cnblogs.com/AnzheWang/p/10453740.html
Copyright © 2011-2022 走看看