• [SDOI2017]数字表格 --- 套路反演


    [SDOI2017]数字表格

    由于使用markdown的关系
    我无法很好的掌控格式,见谅

    对于这么简单的一道题竟然能在洛谷混到黑,我感到无语

    [egin{align*} prodlimits^{n}_{i=1} prodlimits^{m}_{j=1} fi[gcd(i,j)] &= prodlimits^{n}_{d=1} fi[d]^{sumlimits_{e=1}^{n} [n/de][m/de]mu(e)} \ &= prodlimits^{n}_{T = 1} (prodlimits_{d|T} fi[d]^{mu(T/d)})^{[n/T][m/T]} end{align*}]

    两步化完式子后
    只要预处理函数(fprodlimits_{d|n} fi[d]^{mu(n/d)})的前缀积就行
    可以做到(O(n))(fi)(O(n))(mu),枚举因子(O(n logn))求这个函数,(O(n))计算前缀积
    为了方便,我们同时求出他们的逆元即可

    复杂度(O(n logn + Tsqrt n log n))

    代码

    #include <cstdio>
    #include <iostream>
    #define sid 1000050
    #define ll long long
    #define mod 1000000007
    #define ri register int
    using namespace std;
    
    const int N = 1000000;
    ll fi[sid], f[sid], iv[sid];
    int mu[sid], pr[sid], nop[sid], pp, tot;
    
    int read() { scanf("%d", &pp); return pp; }
    
    ll qpow(ll a, ll k) {
        ll ret = 1;
        while(k) {
            if(k & 1) ret = (ret * a) % mod;
            a = (a * a) % mod; k >>= 1;
        }
        return ret;
    }
    
    void Get_Fib() {
        fi[1] = 1; fi[2] = 1;
        for(ri i = 3; i <= N; i ++)
        fi[i] = (fi[i - 1] + fi[i - 2]) % mod;
    }
    
    void Get_Mu() {
        mu[1] = 1;
        for(ri i = 2; i <= N; i ++) {
            if(!nop[i]) { pr[++ tot] = i; mu[i] = -1; }
            for(ri j = 1; j <= tot; j ++) {
                int h = i * pr[j];
                if(h > N) break; nop[h] = 1;
                if(i % pr[j] == 0) { mu[h] = 0; break; }
                else mu[h] = -mu[i];
            }
        }
    }
    
    void Get_f() {
        for(ri i = 1; i <= N; i ++) f[i] = 1;
        for(ri i = 1; i <= N; i ++) {
            ll inv = qpow(fi[i], mod - 2);
            for(ri j = i; j <= N; j += i)
            if(mu[j / i] == -1) f[j] = (f[j] * inv) % mod;
            else if(mu[j / i]) f[j] = (f[j] * fi[i]) % mod;
        }
        f[0] = 1; iv[0] = 1;
        for(ri i = 1; i <= N; i ++) f[i] = (f[i] * f[i - 1]) % mod;
        for(ri i = 1; i <= N; i ++) iv[i] = qpow(f[i], mod - 2);
    }
    
    ll Solve(int n, int m) {
        ll ret = 1;
        if(n > m) swap(n, m);
        for(ri i = 1, j; i <= n; i = j + 1) {
            j = min(n / (n / i), m / (m / i));
            ret = ret * qpow(f[j] * iv[i - 1] % mod, 1ll * (n / i) * (m / i)) % mod;
        }
        return ret;
    }
    
    int main() {
        Get_Fib(); Get_Mu(); Get_f();
        int Tt = read();
        while(Tt --) {
            int n = read(), m = read();
            printf("%lld
    ", Solve(n, m));
        }
        return 0;
    }
    
  • 相关阅读:
    数据挖掘与R语言,数据分析,机器学习
    Linux下bash中关于日期函数date的格式及各种用法
    大数据之机器学习(11)
    unsolved 2 db2 issues
    时间是一剂良药,是制作“知识食物”不可或缺的材料
    b,B,KB,MB,GB
    学习数据结构要再学一遍c语言,害,加油吧
    栈(stack)
    堆(heap)
    js计算器(一)
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9189232.html
Copyright © 2020-2023  润新知