牛客练习赛40 E题 小D的Lemon 莫比乌斯反演

题目描述
あの日の悲しみさえ
那一天的悲伤也好
あの日の苦しみさえ
那一天的痛苦也好
そのすべてを愛してた あなたとともに
我深爱着和你在一起的点点滴滴
胸に残り離れない
残留在心中久久不离
苦いレモンの匂い
苦柠檬的香气
雨が降り止むまでは帰れない
雨停为止都无法回去
切り分けた果実の片方の様に
如同切开的果实的一面那样
今でもあなたはわたしの光
至今为止你依然是我的光
米津玄师—《Lemon》

题目描述

旧日的美好已如昙花般绽放之后消失的无影无踪,只剩下些许的回忆和无穷的悔恨。如梦般的时光已经逝去,但值得庆幸的是,仍有电脑、鼠标、键盘和那一串串的公式无言却忠诚地记录着过去。
小D在时光的缝隙中找到了一个公式
牛客练习赛40 E题 小D的Lemon 莫比乌斯反演_第1张图片

解析

x = ∏ i = 1 q p i k i , g ( x ) = ∑ i = 1 q k i , g ( 1 ) = 1 x=\prod_{i=1}^qp_i^{k_i},g(x)=\sum_{i=1}^qk_i,g(1)=1 x=i=1qpikig(x)=i=1qkig(1)=1
g ( p r i m e ) = 1 , g ( a × p r i m e ) = g ( a ) + 1 g(prime)=1,g(a\times prime)=g(a)+1 g(prime)=1g(a×prime)=g(a)+1所以线性筛的时候,可以顺便把 g ( n ) g(n) g(n)给筛出来。

入门推荐:here

原式子: ∏ i = 1 n ∏ j = 1 m g ( g c d ( i , j ) ) \prod_{i=1}^n\prod_{j=1}^m g(gcd(i,j)) i=1nj=1mg(gcd(i,j))
提取 g c d gcd gcd ∏ d = 1 n g ( d ) ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = d ] \prod_{d=1}^n g(d)^{\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d]} d=1ng(d)i=1nj=1m[gcd(i,j)=d]
反演一下指数那个式子: ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = d ] = ∑ i = 1 n d ∑ j = 1 m d [ g c d ( i , j ) = 1 ] = ∑ i = 1 n d ∑ j = 1 m d ∑ k ∣ g c d ( i , j ) μ ( k ) \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d]=\sum_{i=1}^{\frac nd}\sum_{j=1}^{\frac md}[gcd(i,j)=1]=\sum_{i=1}^{\frac nd}\sum_{j=1}^{\frac md}\sum_{k|gcd(i,j)}\mu(k) i=1nj=1m[gcd(i,j)=d]=i=1dnj=1dm[gcd(i,j)=1]=i=1dnj=1dmkgcd(i,j)μ(k)
得到这个式子: ∏ d = 1 n g ( d ) ∑ k = 1 n d μ ( k ) n k d m k d \prod_{d=1}^n g(d)^{\sum_{k=1}^{\frac nd}\mu(k)\frac{n}{kd}\frac{m}{kd}} d=1ng(d)k=1dnμ(k)kdnkdm
上面这个式子可以 O ( n ) O(n) O(n)求值了,但是还不够,因为这题有多组数据。
想到一个常用的优化方式:
先把指数提下来: ∏ d = 1 n ∏ k = 1 n d g ( d ) μ ( k ) n k d m k d \prod_{d=1}^n \prod_{k=1}^{\frac nd} g(d)^{\mu(k)\frac{n}{kd}\frac{m}{kd}} d=1nk=1dng(d)μ(k)kdnkdm
T = k d T=kd T=kd,换元求积: ∏ T = 1 n ∏ d ∣ T g ( d ) μ ( T d ) n T m T \prod_{T=1}^n\prod_{d|T}g(d)^{\mu(\frac Td)\frac nT \frac mT} T=1ndTg(d)μ(dT)TnTm
再变换一下: ∏ T = 1 n ( ∏ d ∣ T g ( d ) μ ( T d ) ) n T m T \prod_{T=1}^n(\prod_{d|T}g(d)^{\mu(\frac Td)})^{\frac nT \frac mT} T=1n(dTg(d)μ(dT))TnTm
发现这个式子 ∏ d ∣ T g ( d ) μ ( T d ) \prod_{d|T}g(d)^{\mu(\frac Td)} dTg(d)μ(dT)可以 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))预处理出来, O ( 1 ) O(1) O(1)求值。

所以最后总的复杂度是 O ( ( n l o g ( n ) + T n ) × 常 数 ) O((nlog(n)+T\sqrt n)\times常数) O((nlog(n)+Tn )×)

AC_CODE:

#include
#define fi first
#define se second
#define iis std::ios::sync_with_stdio(false);cin.tie(0)
#define pb push_back
#define o2(x) (x)*(x)
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;

const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int MXN = 3e5 + 6;

int n, q, m;
int noprime[MXN], pp[MXN/2], pcnt;
int mu[MXN];
LL g[MXN], inv_g[MXN], f[MXN], pre[MXN], inv_pre[MXN];
LL ksm(LL a, LL b) {
    LL res = 1;
    for(;b;b>>=1,a=a*a%MOD) {
        if(b&1) res=res*a%MOD;
    }
    return res;
}
void init_rime() {
    noprime[0] = noprime[1] = 1;
    mu[1] = g[1] = 1;
    for(int i = 2; i < MXN; ++i) {
        if(!noprime[i]) pp[pcnt++] = i, mu[i]=-1, g[i] = 1;
        for(int j = 0; j < pcnt && i*pp[j] < MXN; ++j) {
            noprime[i*pp[j]] = 1;
            mu[i*pp[j]] = -mu[i];
            g[i*pp[j]] = g[i] + 1;
            if(i % pp[j] == 0) {
                mu[i*pp[j]] = 0;
                break;
            }
        }
    }
    for(int i = 1; i < MXN; ++i) f[i] = 1, inv_g[i] = ksm(g[i], MOD-2);
    for(int i = 2; i < MXN; ++i) {
        for(int j = i; j < MXN; j += i) {
            if(mu[j/i] == 1) f[j] = f[j] * g[i] % MOD;
            else if(mu[j/i] == -1) f[j] = f[j] * inv_g[i] % MOD;
        }
    }
    pre[0] = pre[1] = inv_pre[0] = inv_pre[1] = 1;
    for(int i = 2; i < MXN; ++i) {
        pre[i] = pre[i-1] * f[i] % MOD;
        inv_pre[i] = ksm(pre[i], MOD-2);
    }
}
int main(int argc, char const *argv[]) {
    init_rime();
    int tim;
    scanf("%d", &tim);
    while(tim --) {
        scanf("%d%d", &n, &m);
        LL ans = 1, tmp;
        if(n > m) swap(n, m);
        for(int L = 1, R; L <= n; L = R + 1) {
            R = min(n/(n/L),m/(m/L));
            ans = (ans * ksm(pre[R]*inv_pre[L-1]%MOD, 1LL*(n/L)*(m/L)%(MOD-1)))%MOD;
        }
        printf("%lld\n", ans);
    }    
    return 0;
}

题目类似:bzoj 4816: [Sdoi2017]数字表格

你可能感兴趣的:(------数论------)