• 莫比乌斯反演 学习笔记


    莫比乌斯函数

    定义

    (mu) 表示莫比乌斯函数,是一个由容斥系数所构成的函数, (mu{(d)}) 的定义是:

    1.当d等于1时, (mu{(d)} = 1)

    2.当d由k个不同的质因子组成时,(mu{(d)} = (-1)^k) (注:一定是互不相同的质因子

    3.其它情况(mu{(d)} = 0)



    性质


    1.对于任意正整数n,都有(sumlimits_{d|n}mu{(d)} = [n = 1])

    即当n等于1时 原式等于1,其它情况下 ,原式等于0


    首先当n等于1时 ,显然答案是1

    当n不等于1时,答案与那些(mu)值是0的项肯定没有关系

    现在考虑n有k个互不相同的质因子 它们分别组合

    假定i个质因子相互组合 此时的方案数有(inom{k}{i})

    而此时的(mu)值为((-1)^k)

    所以对于一个非1的n 最终的求和式子也就是

    ((-1)^1*inom{k}{1}+(-1)^2*inom{k}{2}+...+(-1)^k*inom{k}{k}+1)(最后的1是(mu{(1)}) 因为通过质因子相乘是无法组合出1的,所以要把漏掉的情况补上)

    而1又等于((-1)^0*inom{k}{0})

    所以原式就变成了((-1)^0*inom{k}{0}+(-1)^1*inom{k}{1}+(-1)^2*inom{k}{2}+...+(-1)^k*inom{k}{k})

    没有感到这个式子很熟悉?

    不熟悉去找数学老师跪搓衣板

    二项式定理:((a-b)^k = inom{k}{0}a^k*b^0+inom{k}{1}a^{k-1}*b^1+...+inom{k}{k}a^0*b^k)

    所以原式就等于((1-1)^k) 即0



    [sum_{d|n}frac{mu(d)}{d} = frac{varphi_{n}}{n} ]

    [varphi_{n} = sum_{i=1}^{n}[gcd(n,i)] = 1 ]

    [varphi_{n} = sum_{i=1}^{n}sum_{d|gcd(n,i)} mu(d) ]

    (由第一条性质知当且仅当(gcd(i,j)=1)时后面的和式有值,所以成立

    将d提前

    [varphi_{n} = sum_{d|n} mu(d) sum_{i=1}^{frac{n}{d}} ]

    后面的枚举空循环显然是没有意义的

    所以化为

    [varphi_{n} = sum_{d|n} mu(d) * frac{n}{d} ]

    然后两边同除(n) 得到

    [sum_{d|n}frac{mu(d)}{d} = frac{varphi_{n}}{n} ]

    原式得证

    另一种证明:

    由狄利克雷卷积(varphi = id*mu)

    得到(varphi(n)=sum_{d|n}mu(d)cdot frac{n}{d})

    两边同时处理n 得到原式




    筛法比筛一般的积性函数还要简单一点

    void sieve(){
    	mu[1] = 1;
    	for(int i = 2;i <= maxk - 5;++i) {
    		if(!vis[i]) prime[++cnt] = i,mu[i] = -1;
    		for(int j = 1;j <= cnt && prime[j] * i <= maxk - 5;++j) {
    			vis[prime[j]*i] = 1;
    			mu[i*prime[j]] = -mu[i];
    			if(i % prime[j] == 0) {mu[i*prime[j]] = 0;break;}
    		}
    	}
    }
    

    莫比乌斯反演

    前提:(f())是积性函数

    [f(n)=sumlimits_{d|n}g(d) Leftrightarrow g(n)=sumlimits_{d|n}mu(d)f(frac{n}{d}) ]

    证明:

    [sumlimits_{d|n}mu{(d)}*F(frac{n}{d}) = sumlimits_{d|n}mu{(d)}*sumlimits_{k|frac{n}{d}}f(k) = sumlimits_{d|n}f(d)*sumlimits_{k|frac{n}{d}}mu{(k)} = f(n) ]

    关于最后一步:

    首先由性质1知 当(d != n) 时 答案为0

    所以只需要统计当(d = n)时的答案

    所以最后得到(f(n))

    另一种形式:

    [f(n)=sumlimits_{n|d}g(d) Leftrightarrow g(n)=sumlimits_{n|d}mu(frac{d}{n})f(d) ]




    A:P2257 YY的GCD

    题目求(gcd(i,j) epsilon prime)的个数
    写成柿子

    [sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} [gcd(i,j)epsilon prime] ]

    一般套路,(gcd(i,j) = 1) 可以化成(sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} sumlimits_{d|gcd(i,j)}mu{(d)})
    原因很显然

    由莫比乌斯函数性质一:(sumlimits_{d|n}mu{(d)} = [n = 1])

    (gcd(i,j))代入n就好了

    而该题要求的是gcd为素数的

    所以想到可以枚举素数 然后套式子

    假设此时的gcd(i,j) = k

    则答案变为(sumlimits_{k=1}^{n} sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} gcd(i,j)=k)

    此时k一定满足(k|i,k|j)

    也就是(sumlimits_{k=1}^{n} sumlimits_{i=1}^{left lfloor frac{n}{k} ight floor} sumlimits_{j=1}^{left lfloor frac{m}{k} ight floor} sumlimits_{d|gcd(i,j)}mu{(d)})

    发现可以把d提前 然后就变成了(sumlimits_{k=1}^{n} sumlimits_{d=1}^{left lfloor frac{n}{k} ight floor} sumlimits_{i=1}^{left lfloor frac{n}{k*d} ight floor} sumlimits_{j=1}^{left lfloor frac{m}{k*d} ight floor} mu{(d)})

    此时i和j这两维显然就没用了 因为后面的(mu{(d)})与i,j无关

    直接去掉 把加法改成乘法就好了

    (sumlimits_{k=1}^{n} sumlimits_{d=1}^{left lfloor frac{n}{k} ight floor}left lfloor frac{n}{k*d} ight floor*left lfloor frac{m}{k*d} ight floor*mu{(d)})

    然后我们的60分就到手了

    现在考虑优化这个式子

    设T = k*d

    那么有原式等于(sumlimits_{k=1}^{n} sumlimits_{d=1}^{left lfloor frac{n}{k} ight floor}left lfloor frac{n}{T} ight floor*left lfloor frac{m}{T} ight floor*mu{(d)})

    发现此时的T可以提前

    所以原式就变为了(sumlimits_{T=1}^{n} left lfloor frac{n}{T} ight floor*left lfloor frac{m}{T} ight floor sumlimits_{k|T,k epsilon prime}mu{(frac{T}{k})})

    发现(sumlimits_{k|T,k epsilon prime}mu{(frac{T}{k})}) 是可以预处理的

    只要计算一个(mu{(d)})时,把它所有倍数T 都加上一个对应的贡献(mu{(frac{T}{d})})就可以了
    计算前缀和 方便整除分块的时候快速计算贡献

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e7 + 10;
    int prime[maxn];
    int vis[maxn];
    int mu[maxn];
    int cnt;
    int f[maxn];
    ll sum[maxn];
    
    void init(){
    	mu[1] = 1;
    	for(int i = 2;i <= maxn - 5;++i) {
    		if(!vis[i]) vis[i] = 1,prime[++cnt] = i,mu[i] = -1;
    		for(int j = 1;j <= cnt && prime[j] * i <= maxn - 5;++j) {
    			vis[i*prime[j]] = 1;
    			if(i % prime[j] == 0) break;
    			mu[i*prime[j]] = -mu[i];
    		}
    	}
    	for(int i = 1;i <= cnt;++i) 
    		for(int j = 1;j <= maxn && prime[i] * j <= maxn - 5;++j) 
    			f[j*prime[i]] += mu[j];
    	for(int i = 1;i <= maxn - 5;++i) sum[i] = sum[i-1] + f[i];
    }
    
    int main(){
    	init();
    	int T;scanf("%d",&T);
    	while(T--) {
    		int n,m; scanf("%d%d",&n,&m); if(n > m) swap(n,m);
    		ll ans = 0;
    		for(int l = 1,r;l <= n;l = r + 1) {
    			r = min(n/(n/l),m/(m/l));
    			ans += (sum[r] - sum[l-1]) * (n / l) * (m / l);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    B: P3327 约数个数和

    (sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} d(ij))

    难点显然在于如何转化(d(ij))

    (d(ij))可以化成(sumlimits_{x|i}^{i} sumlimits_{y|j}^{j} [gcd(x,y)=1]) 的形式

    考虑(ij)的每个因子 对于每个每个因子一定可以划分成({p_1}^{c1}*{p_2}^{c2}*...)

    规定每个指数首先从i中选 i中不够再从j中选 这样每个因子一定可以找到唯一的一种划分 而每一种划分一定可以对应唯一的因子

    而对于(sumlimits_{x|i}^{i} sumlimits_{y|j}^{j} [gcd(x,y)=1])

    首先(x*y)一定是(i*j)的因子

    (gcd(x,y) = 1) 说明x与y不含有相同的质因子

    考虑划分规则 对于(x=1,y=2)(x=2,y=1) 此时构造出来的因子并不相同 因为y有值的条件是 x已经选完

    所以(y=2)时表示 构造出一个(i)中所有的质因子2都选 (j)中选了一个 而(y=1)时显然不同 所以不会重复

    而因为每一个因子都可以用这样的方法构造出来 所以不会漏掉情况

    然后就是一般的莫比乌斯反演了

    将式子代入可得(sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} sumlimits_{x|i} sumlimits_{y|j} [gcd(x,y)=1])

    (x,y)提前 得到
    (sumlimits_{x=1}^{n} sumlimits_{y=1}^{m} sumlimits_{i|x} sumlimits_{j|y} [gcd(i,j)=1])

    显然后面的枚举可以省掉 得到
    (sumlimits_{x=1}^{n} sumlimits_{y=1}^{m} left lfloor n/x ight floor left lfloor m / y ight floor [gcd(i,j)=1])

    (f(x) = sumlimits_{x=1}^{n} sumlimits_{y=1}^{m} left lfloor n/x ight floor left lfloor m / y ight floor [gcd(i,j)=x])

    (g(x) = sumlimits_{x|d} f(d))

    (g(x) = sumlimits_{x|d} sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} left lfloor n/i ight floor left lfloor m / j ight floor [gcd(i,j)=d])

    发现第一维的枚举可以省掉 变为

    (g(x) = sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} left lfloor n/i ight floor left lfloor m / j ight floor [x|gcd(i,j)])

    将gcd消除 得
    (g(x) = sumlimits_{i=1}^{frac{n}{x}} sumlimits_{j=1}^{frac{m}{x}} left lfloor n/ix ight floor left lfloor m/jx ight floor)

    然后移项得到
    (g(x) = sumlimits_{i=1}^{frac{n}{x}} left lfloor n / ix ight floor sumlimits_{j=1}^{frac{m}{x}} left lfloor m/jx ight floor)

    预处理出(f(x) = sumlimits_{i=1}^{x}left lfloor x/i ight floor)

    然后就可以O(1)计算g函数了

    又有(f(x) = sumlimits_{x|d} mu(d/x) g(d))

    (f(1) = sumlimits_{i=1}^{n} mu(i) g(i))

    (f(1) = sumlimits_{x=1}^{n} mu(x)sumlimits_{i=1}^{frac{n}{x}} left lfloor n / ix ight floor sumlimits_{j=1}^{frac{m}{x}} left lfloor m/jx ight floor)

    后面的部分可以整除分块优化成根号

    C:P4449 于神之怒加强版

    (假定(n <= m))

    首先原式可以化为

    (sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} sumlimits_{d=1}^{n} [gcd(i,j)=d] * d^k)

    移项 得

    (sumlimits_{d=1}^{n} d^k sumlimits_{i=1}^{n} sumlimits_{j=1}^{m} [gcd(i,j)=d])


    (sumlimits_{d=1}^{n} d^k sumlimits_{i=1}^{left lfloor frac{n}{d} ight floor}sumlimits_{j=1}^{left lfloor frac{m}{d} ight floor}[gcd(i,j)=1])

    一般套路将gcd消除得到

    (sumlimits_{d=1}^{n} d^k sumlimits_{i=1}^{left lfloor frac{n}{d} ight floor}sumlimits_{j=1}^{left lfloor frac{m}{d} ight floor}sumlimits_{k|gcd(i,j)} mu(k))

    将k提前 得

    (sumlimits_{d=1}^{n} d^k sumlimits_{k=1}^{left lfloor frac{n}{d} ight floor} sumlimits_{i=1}^{left lfloor frac{n}{dk} ight floor}sumlimits_{j=1}^{left lfloor frac{m}{dk} ight floor} mu(k))

    发现后面的式子跟(i,j)没有关系 ,即

    (sumlimits_{d=1}^{n} d^k sumlimits_{k=1}^{left lfloor frac{n}{d} ight floor} left lfloor frac{n}{dk} ight floor left lfloor frac{m}{dk} ight floor mu(k))

    (T=dk)

    (sumlimits_{d=1}^{n}d^k sumlimits_{k=1}^{left lfloor frac{n}{d} ight floor} left lfloor frac{n}{T} ight floor left lfloor frac{m}{T} ight floor mu(k))

    将枚举d改为枚举T 有

    (sumlimits_{T=1}^{n} left lfloor frac{n}{T} ight floor left lfloor frac{m}{T} ight floor sumlimits_{d|T}mu(frac{T}{k}) * d^k)

    发现后面的部分可以预处理

    (g(x) = sumlimits_{d|x}mu(frac{x}{k}) * d^k)

    (g(x))为积性函数

    所以可以线性筛把(g())函数筛出来

    一个质数(p)的函数值可以算出 等于(p^k-1)

    考虑(g[i*prime[j]]) 如果(i)(prime[j])互质 显然可以直接乘起来 得到函数值

    如果(i) % (prime[j] != 0)时 考虑如何快速求出函数值

    发现(i)一定可以表示为({p_1}^{c_1}*{p_2}^{c2}*...)

    (prime[j])后一定是 ({p_1}^{c_1+1} * {p_2}^{c2} * ...)

    后面的部分完全一样

    所以考虑如何计算前面的部分

    因为(g[i*prime[j]] = g[i] / g[{p_1}^{c1}] * g[{p_1}^{c1+1}])

    对于后面的部分 等于

    (sumlimits_{d|{p_1}^{c_1+1}}mu(frac{{p_1}^{c_1+1}}{d}) * d^k)

    (mu)函数定义可知 只有当(d)({p_1}^{c_1+1}) 或者 ({p_1}^{c_1})(mu)值不为0

    得到(g[{p_1}^{c1+1}] = {{p_1}^{(c_1+1)}}^k - {{p_1}^{c_1}}^k = {{p_1}^{c_1}}^k *( {p_1}^{k} - 1))

    (g[{p_1}^{c1}] = {{p_1}^{c_1}}^k - {{p_1}^{(c_1-1)}}^k = {{p_1}^{(c_1-1)}}^k *( {p_1}^{k} - 1))

    所以(g[{p_1}^{c1+1}] = g[{p_1}^{c1}] * {p_1}^k)

    所以就可以线性筛了

    筛完之后 处理一下前缀和 然后整除分块就可以了




    D:jzptab

    很套路的题

    (sum_{i=1}^{n}sum_{j=1}^{m}lcm(i,j))

    (sum_{i=1}^{n}sum_{j=1}^{m}frac{ij}{gcd(i,j)})

    枚举gcd

    (sum_{d=1}^{n}frac{1}{d}sum_{i=1}^{n}sum_{j=1}^{m} ij*[(i,j)=d])

    (sum_{d=1}^{n}frac{1}{d}sum_{i=1}^{frac{n}{d}}sum_{j=1}^{frac{m}{d}} ij*d^2*[(i,j)=1])

    发现(d^2)可以提前 得到

    (sum_{d=1}^{n} dsum_{i=1}^{frac{n}{d}}sum_{j=1}^{frac{m}{d}} ij*[(i,j)=1])

    ([(i,j)=1]) 展开

    (sum_{d=1}^{n} dsum_{i=1}^{frac{n}{d}}sum_{j=1}^{frac{m}{d}} ij sum_{k|gcd(i,j)} mu(k))

    交换枚举顺序

    (sum_{d=1}^{n} d sum_{k=1}^{frac{n}{d}}mu(k) sum_{i=1}^{frac{n}{dk}}sum_{j=1}^{frac{m}{dk}} ij*k^2)

    (k^2) 提前得到
    (sum_{d=1}^{n} d sum_{k=1}^{frac{n}{d}}k^2mu(k) sum_{i=1}^{frac{n}{dk}}sum_{j=1}^{frac{m}{dk}} ij)

    Solution1:

    到这里已经可以过掉洛谷的数据了 单组询问,时限2s

    (sum_{i=1}^{frac{n}{dk}}sum_{j=1}^{frac{m}{dk}} ij) 就是两个等差数列乘起来

    所以可以用整除分块做到根号复杂度

    发现对于n来说,(sum_{k=1}^{frac{n}{d}}k^2mu(k)) 也可以整除分块处理

    所以两个整除分块处理 O(n)预处理 O((n^frac{3}{4}))回答每次询问


    Solution2:

    但是另一个数据范围是时限8s,1e4组询问

    上面的式子可以继续化简

    (T = dk)

    (sum_{T=1}^{n} sum_{k|T} k^2mu(k)*frac{T}{k}sum_{i=1}^{frac{n}{T}} sum_{j=1}^{frac{m}{T}}ij)

    中间的部分可以(nln)预处理 后面的部分可以整除分块

    一个小trick是当(mu(i)=0)时直接跳过,可以减小一半常数

    然后就可以做到(O(nln))预处理 (O(sqrt{n}))处理单组询问


    Solution3:

    但是我们可以做到更优秀的时间复杂度

    复杂度瓶颈显然在预处理 考虑怎么优化这个过程

    发现可以把原式再化一下变成

    (sum_{T=1}^{n} Tsum_{k|T} k*mu(k)sum_{i=1}^{frac{n}{T}} sum_{j=1}^{frac{m}{T}}ij)

    (F[n] = sum_{k|n} k * mu(k))

    然后发现中间的式子就是个积性函数

    关于为什么是积性函数 两个积性函数对位相乘显然是积性函数

    (id)(mu) 都是积性函数 所以这东西也是积性函数

    然后就可以线性筛了

    只需要考虑特殊情况:

    p为质数 (F[p] = 1 - p)

    (p^k) 考虑原式,只有当因子等于(1)或p时(mu)值不为0

    所以(F[p^k] = 1-p)

    (low[i]) 表示i的(p_1^{c1}) 即i最小质因子的贡献

    所以(F[i*prime[j]] = F[i/low[i]] * F[low[i]*prime[j]])

    (low[i]*prime[j]) 一定是(p^k) 的形式

    所以(F[i*prime[j]] = F[i/low[i]] *F[low[i]] = F[i])

    所以就可以线性筛了


    Solution4:

    还是考虑优化预处理的部分

    发现中间的式子完全就是狄利克雷前缀和的模板 然后就可以做了




    E: 数表

    需要一点点小转化 之前没有见过这种套路记录一下

    首先不考虑a的限制

    (f[i])表示i的约数和

    列出式子

    求 $sum_{i=1}^{n} sum_{j=1}^{m} f[gcd(i,j)] $

    简单化一下有

    (sum_{d=1}^{n} sum_{i=1}^{n} sum_{j=1}^{m} f[d] * [gcd(i,j)=d])

    很显然的式子了 推过好多遍的 直接到终态

    (sum_{T=1}^{n}sum_{d|T}f(d)mu(frac{T}{d}) left lfloor frac{n}{T} ight floorleft lfloor frac{m}{T} ight floor)

    如果没有a的限制我们到这里就做完了

    考虑有a的限制怎么办

    a的限制是对于(f(d))

    所以可以对于(f(d))按照权值排序

    对于询问按照a排序

    每次暴力加入一些新的(f(d)) 并更新前缀和

    然后整除分块回答询问

    更新前缀和可以套一个树状数组 就很方便了

    一共会更新(nln)次答案,每次更新答案复杂度为(log) 所以修改总复杂度为(nln*log)

    每次回答询问是(O(sqrt{n}))





    F:数字表格

    挺新的套路

    (prod_{i=1}^{n} prod_{j=1}^{m}f[gcd(i,j)])

    这个题不同的地方在于变成了乘法,先化式子

    (prod_{d=1}^{n}prod_{i=1}^{n} prod_{j=1}^{m} f[d]^{[gcd(i,j)=d]})

    连乘可以放到指数上去 所以

    (prod_{d=1}^{n}f[d]^{sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)=d]})

    一般套路

    (prod_{d=1}^{n}f[d]^{sum_{i=1}^{frac{n}{d}}sum_{j=1}^{frac{m}{d}}[gcd(i,j)=1]})

    (prod_{d=1}^{n}f[d]^{sum_{i=1}^{frac{n}{d}}sum_{j=1}^{frac{m}{d}}sum_{k|gcd(i,j)}mu(k)})

    (prod_{d=1}^{n}f[d]^{sum_{k=1}^{frac{n}{d}} mu(k) sum_{i=1}^{frac{n}{dk}}sum_{j=1}^{frac{m}{dk}}})

    然后把k放到外边

    (prod_{d=1}^{n}prod_{k=1}^{frac{n}{d}}f[d]^{ mu(k) sum_{i=1}^{frac{n}{dk}}sum_{j=1}^{frac{m}{dk}}})

    令T=dk

    改为枚举T, 原式变为

    (prod_{T=1}^{n}prod_{d|T} f(d)^{mu(frac{T}{d})frac{n}{T}frac{m}{T}})

    原式等于(prod_{T=1}^{n}(prod_{d|T} f(d)^{mu(frac{T}{d})})^{frac{n}{T}frac{m}{T}})

    外面的部分显然可以整除分块 , 里面的部分直接暴力就可以了




    G:DZY Loves Math

    (sum_{i=1}^{n}sum_{j=1}^{m}f(gcd(i,j)))

    (sum_{d=1}^{n}f(d)sum_{k=1}^{frac{n}{d}}mu(k)sum_{i=1}^{frac{n}{dk}}sum_{j=1}^{frac{m}{dk}}) (中间的步骤都是套路就直接跳过了)

    令T=dk

    (sum_{T=1}^{n} sum_{d|T}f(d)mu(frac{T}{d})frac{n}{dk}frac{m}{dk})

    显然重点在于把中间的部分处理掉

    (g(T) = sum_{d|T}f(d)mu(frac{T}{d}))

    考虑怎么求这个函数

    首先我们要求的一定是(mu)值不为0的项

    将T分解为(p_1^{a_1}*p_2^{a_2}*...*p_k^{a_k})

    将d分解后

    我们选择的(cnt_i)一定满足(a_i-1 <= cnt_i <= a_i) 这样的项才会对答案造成贡献

    而考虑存在(i,j)其中(a_i<a_j) 那么此时这个(g(T))一定为0

    因为选或者不选i ,对于答案是没有影响的((f)函数的定义)

    而选i与不选i时的(mu)值是恰好互为相反数的,所以这样的项对答案的贡献为0

    而当所有(a_i = a_j)时,我们可以假设此时所有的f值都等于(a_i)

    那么这时候的根据刚刚的思路 可以把所有数分成两部分 一部分是选到(a_i)的 ,另一部分是选到(a_i-1)

    第二部分选到奇数个与偶数个的方案数显然是相等的 所以答案仍是0

    但是当选的所有的都为(a_i-1)时,此时答案为(a_i-1) 并不是我们设的(a_i)

    所以要把这个(-1)的贡献算上 , 此时贡献就是((-1)^{k+1})

    然后转移就很显然了

    如初见 与初见
  • 相关阅读:
    [php]php设计模式 Command(命令模式)
    [php]php设计模式 Observer(观察者模式)
    [转]Ubuntu 系统安装极点五笔
    [转] 关于开源协议
    上传大小限制设置
    php开启安全模式后禁用的函数
    [php]php设计模式 Template (模板模式)
    [php]php设计模式 Singleton(单例模式)
    [php]php设计模式 Strategy(策略模式)
    [转]调优您的 LAMP 应用程序的 5 种简单方法
  • 原文地址:https://www.cnblogs.com/HISKrrr/p/13858246.html
Copyright © 2020-2023  润新知