莫比乌斯反演学习笔记

6 篇文章 0 订阅

Imagine大佬的博客帮助下整了一周莫某某反演,总结一下学的一些新东西和我做的水题的一些小套路;

本篇文章没有对反演进行证明,只是记录了一些理解与做题时遇到的感觉挺有用的小技巧

首先是莫比乌斯函数 μ \mu μ

μ ( x ) = { x = 1                       1 x = p 1 1 ∗ p 2 1 ∗ p 3 1 . . . ∗ p k 1       ( − 1 ) k O t h e r                     0 \mu(x)=\begin{cases} x=1\           1\\ x=p_1^1*p_2^1*p_3^1...*p_k^1   (-1)^k\\ Other          0\\ \end{cases} μ(x)=x=1           1x=p11p21p31...pk1   (1)kOther          0

∑ d ∣ n μ ( d ) = [ n = 1 ] \sum_{d|n}\mu(d)=[n=1] dnμ(d)=[n=1]
是积性函数
可以用线性筛在 O ( n ) O(n) O(n)的时间内得到

void Prepare() {
	mu[1]=1;
	for(int i=2;i<=MAX;++i) {
		if(!sign[i]) pri[++cnt]=i,mu[i]=i-1;
		for(int j=1;i*pri[j]<=MAX;++j) {
			sign[i*pri[j]]=true;
			if(i%pri[j]==0) {
				mu[i*pri[j]]=0;
				break;
			}
			else mu[i*pri[j]]=-mu[i];
		}
	}
}

丢一道题BZOJ2440,容斥的时候也可以考虑一下莫比乌斯函数;

然后是狄利克雷卷积

有两个数列函数 f f f, g g g,它们的狄利克雷卷积定义为 ( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) ∗ g ( n d ) (f*g)(n)=\sum_{d|n}f(d)*g(\frac{n}{d}) (fg)(n)=dnf(d)g(dn);
f f f g g g都是积性函数,则它们的狄利克雷卷积也为积性函数;
狄利克雷卷积满足交换律、结合律,对加法满足分配律

最后是莫比乌斯反演

先说反演,反演在干个什么事呢,我的理解就是给了你一些已知量,然后未知量和已知量直接有某种运算关系,然后通过已知量反解出未知量的过程就是反演;
而莫比乌斯反演也是干这样的事,若函数 f f f, g g g满足这样的关系:
f ( n ) = ∑ d ∣ n g ( d ) f(n)=\sum_{d|n}g(d) f(n)=dng(d)那么有: g ( n ) = ∑ d ∣ n μ ( n d ) ∗ f ( d ) g(n)=\sum_{d|n}\mu(\frac{n}{d})*f(d) g(n)=dnμ(dn)f(d)这个式子证明的话比较简单,考虑狄利克雷卷积 f = g ∗ I f=g*I f=gI( I I I为恒等函数 I ( n ) = 1 I(n)=1 I(n)=1,完全积性),然后同时在两边卷上一个 μ \mu μ, f ∗ μ = g ∗ I ∗ μ = g ∗ e = g f*\mu=g*I*\mu=g*e=g fμ=gIμ=ge=g( e e e为狄利克雷卷积的乘法单位元函数 e ( n ) = [ n = 1 ] e(n)=[n=1] e(n)=[n=1],完全积性);
这个式子还有另一种形式:
f ( n ) = ∑ n ∣ d g ( d ) f(n)=\sum_{n|d}g(d) f(n)=ndg(d)那么 g ( n ) = ∑ n ∣ d μ ( d n ) ∗ f ( d ) g(n)=\sum_{n|d}\mu(\frac{d}{n})*f(d) g(n)=ndμ(nd)f(d)
这个的具体证明也是大力展开式子,具体可看其他人博客(逃

有了这两个关系式之后我们能干些啥事呢?
就像刚刚所说,我们可以通过很快算出其中一个函数的取值,再通过莫比乌斯反演反解出另一个函数,从而大大降低复杂度;

(接下来如果式子中同时出现了 n n n m m m,默认 n ≤ m n\leq m nm);

来看道例题BZOJ1101
这道题需要求的就是 ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = d ] \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d] i=1nj=1m[gcd(i,j)=d]
设函数 g ( d ) = ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = d ] g(d)=\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d] g(d)=i=1nj=1m[gcd(i,j)=d],我们发现主要的困难点就是这个 g ( d ) g(d) g(d)感觉起码要花 O ( n 2 ) O(n^2) O(n2)的代价去算这个东西,有多组询问这样复杂度就变成了 O ( n 3 ) O(n^3) O(n3)以上了,怎么办呢,想起莫比乌斯反演,如果我们能找一个满足反演式子,切算起来复杂度很低的式子,我们是不是就能够很快解决这个问题呢?这题的这个式子很好找而且很套路,设 f ( k ) = ∑ i = 1 n ∑ j = 1 m [ k ∣ g c d ( i , j ) ] f(k)=\sum_{i=1}^n\sum_{j=1}^m[k|gcd(i,j)] f(k)=i=1nj=1m[kgcd(i,j)], f ( k ) f(k) f(k)就相当于找 g c d ( i , j ) gcd(i,j) gcd(i,j) k k k的倍数的 i , j i,j i,j对数,这样是可以 f f f直接算出来的,有 f ( k ) = ⌊ n k ⌋ ⌊ m k ⌋ f(k)=\left \lfloor\frac{n}{k}\right\rfloor\left\lfloor\frac{m}{k}\right\rfloor f(k)=knkm,那么进行反演
f ( k ) = ∑ k ∣ d g ( d ) f(k)=\sum_{k|d}g(d) f(k)=kdg(d)
g ( d ) = ∑ d ∣ k μ ( k d ) f ( k ) g(d)=\sum_{d|k}\mu(\frac{k}{d})f(k) g(d)=dkμ(dk)f(k) g ( d ) = ∑ i = 1 ⌊ n d ⌋ μ ( i ) f ( i d ) g(d)=\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\mu(i)f(id) g(d)=i=1dnμ(i)f(id) g ( d ) = ∑ i = 1 ⌊ n d ⌋ μ ( i ) ⌊ n i d ⌋ ⌊ m i d ⌋ g(d)=\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\mu(i)\left \lfloor\frac{n}{id}\right\rfloor\left\lfloor\frac{m}{id}\right\rfloor g(d)=i=1dnμ(i)idnidm现在我们只需要O(n)的时间,便能完成一次询问了,但是还不够,因为这道题是多组询问,这个时候就要用的一个非常常用的小技巧数论分块了;
当式子里出现这么个东西 ∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^n\left \lfloor\frac{n}{i}\right\rfloor i=1nin,考虑 ⌊ n i ⌋ \left \lfloor\frac{n}{i}\right\rfloor in的取值,很容易看出当 1 ≤ i ≤ n 1\leq i\leq \sqrt n 1in 的时候 ⌊ n i ⌋ \left \lfloor\frac{n}{i}\right\rfloor in最多有 n \sqrt n n 个取值,当 n ≤ i ≤ n \sqrt n\leq i\leq n n in的时候, ⌊ n i ⌋ \left \lfloor\frac{n}{i}\right\rfloor in也最多只有 n \sqrt n n 个取值,且这些区间是连续的,那么我们就可以一次性把所有取值相同的 i i i一起算完,比如 i = d i=d i=d的时候是一个新取值区间的左端点,右端点便是 ⌊ n ⌊ n i ⌋ ⌋ \left \lfloor\frac{n}{\left \lfloor\frac{n}{i}\right\rfloor}\right\rfloor inn,那么在 O ( n ) O(\sqrt n) O(n )的时间内我们就能得到 ∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^n\left \lfloor\frac{n}{i}\right\rfloor i=1nin的答案;
⌊ n i d ⌋ ⌊ m i d ⌋ \left \lfloor\frac{n}{id}\right\rfloor\left\lfloor\frac{m}{id}\right\rfloor idnidm同理,只是注意在取右端点的时候要取更靠左的那一个,详细看代码;

#include<bits/stdc++.h>
#define Fst first
#define Snd second
#define RG register
#define mp make_pair
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
typedef long double LD;
typedef unsigned int UI;
typedef unsigned long long ULL;
template<typename T> inline void read(T& x) {
	char c = getchar();
	bool f = false;
	for (x = 0; !isdigit(c); c = getchar()) {
		if (c == '-') {
			f = true;
		}
	}
	for (; isdigit(c); c = getchar()) {
		x = x * 10 + c - '0';
	}
	if (f) {
		x = -x;
	}
}
template<typename T, typename... U> inline void read(T& x, U& ... y) {
	read(x), read(y...);
}
const int MAX=5e4,N=MAX+10;
int cnt,Q;
int pri[N],mu[N];
bool sign[N];
void Prepare() {
	mu[1]=1;
	for(int i=2;i<=MAX;++i) {
		if(!sign[i]) pri[++cnt]=i,mu[i]=-1;
		for(int j=1;i*pri[j]<=MAX;++j) {
			sign[i*pri[j]]=true;
			if(i%pri[j]==0) {
				mu[i*pri[j]]=0;
				break;
			}
			else mu[i*pri[j]]=-mu[i];
		}
	}
	for(int i=1;i<=MAX;++i) mu[i]+=mu[i-1];
}
LL Calc(int n,int m,int d) {
	if(n>m) swap(n,m);
	n/=d; m/=d;
	LL res=0;
	for(int i=1;i<=n;++i) {
		int p=min(n/(n/i),m/(m/i));
		res+=1ll*(mu[p]-mu[i-1])*(n/i)*(m/i);
		i=p;
	}
	return res;
}
int main() {
#ifdef rua
	freopen("GG.out","w",stdout);
#endif
	Prepare();
	read(Q);
	while(Q--) {
		int n,m,d; read(n,m,d);
		printf("%lld\n",Calc(n,m,d));
	}
	return 0;
}

接下来的题每道都会带一些小技巧,比如式子的替换或者一些函数怎么拆开;

接下来的除法,除非做特殊说明否则都是向下取整(向下取整符号真的难打

BZOJ2154
这题是叫你求 ∑ i = 1 n ∑ j = 1 m l c m ( i , j ) \sum_{i=1}^n\sum_{j=1}^mlcm(i,j) i=1nj=1mlcm(i,j)
看到 l c m lcm lcm往往要拆成 g c d gcd gcd,所以式子化为 ∑ i = 1 n ∑ j = 1 m i j g c d ( i , j ) \sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)} i=1nj=1mgcd(i,j)ij
然后提 g c d gcd gcd出来
∑ d = 1 n ∑ i = 1 n ∑ j = 1 m i j d [ g c d ( i , j ) = d ] \sum_{d=1}^n\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{d}[gcd(i,j)=d] d=1ni=1nj=1mdij[gcd(i,j)=d]
再把 d d d提出来方便分析
∑ d = 1 n ∑ i = 1 n d ∑ j = 1 m d i d j d d [ g c d ( i , j ) = 1 ] \sum_{d=1}^n\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}\frac{idjd}{d}[gcd(i,j)=1] d=1ni=1dnj=1dmdidjd[gcd(i,j)=1]
∑ d = 1 n d ∑ i = 1 n d ∑ j = 1 m d i j [ g c d ( i , j ) = 1 ] \sum_{d=1}^nd\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}ij[gcd(i,j)=1] d=1ndi=1dnj=1dmij[gcd(i,j)=1]
有这个 i j ij ij在后面卡着我们不好反演,这时想起一个好东西 ∑ d ∣ n = [ n = 1 ] \sum_{d|n}=[n=1] dn=[n=1],我们正好把后面的 g c d gcd gcd换了;
∑ d = 1 n d ∑ i = 1 n d ∑ j = 1 m d i j ∑ x ∣ i , x ∣ j μ ( x ) \sum_{d=1}^nd\sum_{i=1}^{\frac{n}{d}}\sum_{j=1}^{\frac{m}{d}}ij\sum_{x|i,x|j}\mu(x) d=1ndi=1dnj=1dmijxi,xjμ(x);
遇到枚举因子的就尝试把因子提到前面来;
∑ d = 1 n d ∑ x = 1 n d μ ( x ) ∑ i = 1 n d x ∑ j = 1 m d x i x j x \sum_{d=1}^nd\sum_{x=1}^{\frac{n}{d}}\mu(x)\sum_{i=1}^{\frac{n}{dx}}\sum_{j=1}^{\frac{m}{dx}}ixjx d=1ndx=1dnμ(x)i=1dxnj=1dxmixjx;
∑ d = 1 n d ∑ x = 1 n d μ ( x ) x 2 ∑ i = 1 n d x ∑ j = 1 m d x i j \sum_{d=1}^nd\sum_{x=1}^{\frac{n}{d}}\mu(x)x^2\sum_{i=1}^{\frac{n}{dx}}\sum_{j=1}^{\frac{m}{dx}}ij d=1ndx=1dnμ(x)x2i=1dxnj=1dxmij;
S u m ( a , b ) = ∑ i = 1 a ∑ j = 1 b i j Sum(a,b)=\sum_{i=1}^a\sum_{j=1}^bij Sum(a,b)=i=1aj=1bij,这个东西其实也是可以直接算的,它显然等于 a ∗ ( a + 1 ) 2 ∗ b ∗ ( b + 1 ) 2 \frac{a*(a+1)}{2}*\frac{b*(b+1)}{2} 2a(a+1)2b(b+1),那么
∑ d = 1 n d ∑ x = 1 n d μ ( x ) x 2 S u m ( n d x , m d x ) \sum_{d=1}^nd\sum_{x=1}^{\frac{n}{d}}\mu(x)x^2Sum(\frac{n}{dx},\frac{m}{dx}) d=1ndx=1dnμ(x)x2Sum(dxn,dxm);
那么我们可以在算 S u m Sum Sum的时候分块一次,算整体的 ∑ x = 1 n d μ ( x ) x 2 S u m ( n d x , m d x ) \sum_{x=1}^{\frac{n}{d}}\mu(x)x^2Sum(\frac{n}{dx},\frac{m}{dx}) x=1dnμ(x)x2Sum(dxn,dxm)时候又分块一次,这样我们便能在 O ( n ) O(n) O(n)的时间内解决这道题了;
接着看这道题的加强版BZOJ2693
在上一题的基础上,这题变成了多组询问, O ( n ) O(n) O(n)的复杂度似乎还是不够优秀,我们继续推式子 ∑ d = 1 n d ∑ x = 1 n d μ ( x ) x 2 S u m ( n d x , m d x ) \sum_{d=1}^nd\sum_{x=1}^{\frac{n}{d}}\mu(x)x^2Sum(\frac{n}{dx},\frac{m}{dx}) d=1ndx=1dnμ(x)x2Sum(dxn,dxm)
这也是个常用技巧,设 T = d x T=dx T=dx,我们变换下标,把它提到前面去看看怎么样 ∑ T = 1 n S u m ( n T , m T ) ∑ d ∣ T d ∗ μ ( T d ) ∗ ( T d ) 2 \sum_{T=1}^nSum(\frac{n}{T},\frac{m}{T})\sum_{d|T}d*\mu(\frac{T}{d})*(\frac{T}{d})^2 T=1nSum(Tn,Tm)dTdμ(dT)(dT)2
现在我们来观察一下后面这坨东西
∑ d ∣ T d ∗ μ ( T d ) ∗ ( T d ) 2 \sum_{d|T}d*\mu(\frac{T}{d})*(\frac{T}{d})^2 dTdμ(dT)(dT)2
d d d ( T d ) 2 (\frac{T}{d})^2 (dT)2都可以看作幂函数 i d k ( n ) = n k id^k(n)=n^k idk(n)=nk,完全积性, μ \mu μ函数,积性函数;

                                      在这里插入图片描述

这坨东西好像可以筛;

g ( n ) = ∑ d ∣ n d ∗ μ ( n d ) ∗ ( n d ) 2 g(n)=\sum_{d|n}d*\mu(\frac{n}{d})*(\frac{n}{d})^2 g(n)=dndμ(dn)(dn)2
现在考虑 n = 1 n=1 n=1 g ( n ) = 1 g(n)=1 g(n)=1
n n n为质数时, d d d只有 1 1 1 n n n两种取值,此时 g ( n ) = n − n 2 g(n)=n-n^2 g(n)=nn2
n n n不为质数时,考虑唯一分解定理 g ( n ) = ∏ p i 为 n 的 质 因 子 t g ( p i c i ) g(n)=\prod_{p_i为n的质因子}^tg(p_i^{c_i}) g(n)=pintg(pici)
考虑线性筛的两种情况,第一种 i % p r i [ j ] ! = 0 i\%pri[j]!=0 i%pri[j]!=0时,因为 g g g是积性函数, g ( i ∗ p r i [ j ] ) = g ( i ) ∗ g ( p r i [ j ] ) g(i*pri[j])=g(i)*g(pri[j]) g(ipri[j])=g(i)g(pri[j])
否则考虑新进来一个质数 p p p会增加怎样的新因子,因为如果 μ ( d ) \mu(d) μ(d) d d d中含有二次以上的因子,必然会等于 0 0 0,此时发现原来那些有效的因子 d d d,乘上一个 p p p后继续有效,其他的 d d d都因为 n d \frac{n}{d} dn含有了二次以上的因子导致 μ ( d ) = 0 \mu(d)=0 μ(d)=0可以不用考虑了,所以此时的 g ( i ∗ p r i [ j ] ) = g ( i ) ∗ p r i [ j ] g(i*pri[j])=g(i)*pri[j] g(ipri[j])=g(i)pri[j];
所以我们可以用线性筛先预处理出所有的 g ( T ) g(T) g(T),现在式子变成 ∑ T = 1 n S u m ( n T , m T ) g ( T ) \sum_{T=1}^nSum(\frac{n}{T},\frac{m}{T})g(T) T=1nSum(Tn,Tm)g(T)
再加上除法分块,我们便能在 O ( n ) O(\sqrt n) O(n )的时间内完成一次询问了;

#include<bits/stdc++.h>
#define Fst first
#define Snd second
#define RG register
#define mp make_pair
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
typedef long double LD;
typedef unsigned int UI;
typedef unsigned long long ULL;
template<typename T> inline void read(T& x) {
	char c = getchar();
	bool f = false;
	for (x = 0; !isdigit(c); c = getchar()) {
		if (c == '-') {
			f = true;
		}
	}
	for (; isdigit(c); c = getchar()) {
		x = x * 10 + c - '0';
	}
	if (f) {
		x = -x;
	}
}
template<typename T, typename... U> inline void read(T& x, U& ... y) {
	read(x), read(y...);
}
const int MAX=1e7,N=MAX+10,P=20101009;
int cnt,T;
int F[N],G[N],pri[N];
bool sign[N];
void Prepare() {
	F[1]=1;
	for(int i=2;i<=MAX;++i) {
		if(!sign[i]) pri[++cnt]=i,F[i]=(i-1ll*i*i%P+P)%P;
		for(int j=1;i*pri[j]<=MAX;++j) {
			sign[i*pri[j]]=true;
			if(i%pri[j]==0) {
				F[i*pri[j]]=1ll*F[i]*pri[j]%P;
				break;
			}
			else F[i*pri[j]]=1ll*F[i]*F[pri[j]]%P;
		}
	}
	for(int i=1;i<=MAX;++i) F[i]=(F[i]+F[i-1])%P,G[i]=(1ll*i*(i+1)/2ll)%P;
}
int Calc(int n,int m) {
	if(n>m) swap(n,m);
	int res=0;
	for(int i=1;i<=n;++i) {
		int p=min(n/(n/i),m/(m/i));
		res=(res+1ll*((F[p]-F[i-1])%P+P)%P*G[n/i]%P*G[m/i]%P)%P;
		i=p;
	}
	return res;
}
int main() {
#ifdef rua
	freopen("GG.out","w",stdout);
#endif
	Prepare();
	T=1;
	while(T--) {
		int n,m; read(n,m);
		printf("%d\n",Calc(n,m));
	}
	return 0;
}

BZOJ2005
这题抽象一下之后,我们的重点就是求 ∑ i = 1 n ∑ j = 1 m g c d ( i , j ) \sum_{i=1}^n\sum_{j=1}^mgcd(i,j) i=1nj=1mgcd(i,j)
本题可以用上面那个 O ( n ) O(\sqrt n) O(n )的反演求 g c d = d gcd=d gcd=d的个数暴力去跑 n n n次得到答案;
但是这里要介绍另外一种方法,因为这个方法经常用于式子的替换上;
这里不再是,求个数了,而是具体的和,于是可以用的欧拉函数 φ \varphi φ的一个性质 n = ∑ d ∣ n φ ( d ) n=\sum_{d|n}\varphi(d) n=dnφ(d)
于是式子变成了这样 ∑ i = 1 n ∑ j = 1 m ∑ d ∣ i , d ∣ j φ ( d ) \sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}\varphi(d) i=1nj=1mdi,djφ(d)
很套路的把 d d d提到前面来 ∑ d = 1 n φ ( d ) n d m d \sum_{d=1}^n\varphi(d)\frac{n}{d}\frac{m}{d} d=1nφ(d)dndm
数论分块一下,跑的比反演不知道快到哪里去了了;

#include<bits/stdc++.h>
#define Fst first
#define Snd second
#define RG register
#define mp make_pair
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
typedef long double LD;
typedef unsigned int UI;
typedef unsigned long long ULL;
template<typename T> inline void read(T& x) {
    char c = getchar();
    bool f = false;
    for (x = 0; !isdigit(c); c = getchar()) {
        if (c == '-') {
            f = true;
        }
    }
    for (; isdigit(c); c = getchar()) {
        x = x * 10 + c - '0';
    }
    if (f) {
        x = -x;
    }
}
template<typename T, typename... U> inline void read(T& x, U& ... y) {
    read(x), read(y...);
}
const int MAX=1e5,N=MAX+10;
int cnt;
int pri[N];
bool sign[N];
LL phi[N];
void Prepare() {
    phi[1]=1;
    for(int i=2;i<=MAX;++i) {
        if(!sign[i]) pri[++cnt]=i,phi[i]=i-1;
        for(int j=1;i*pri[j]<=MAX;++j) {
            sign[i*pri[j]]=true;
            if(i%pri[j]==0) {
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
            else phi[i*pri[j]]=phi[i]*phi[pri[j]];
        }
    }
    for(int i=1;i<=MAX;++i) phi[i]+=phi[i-1];
}
int main() {
#ifdef rua
    freopen("GG.in","r",stdin);
#endif
    Prepare();
    int n,m; read(n,m);
    if(n>m) swap(n,m);
    LL res=-1ll*n*m;
    for(int i=1;i<=n;++i) {
    	int p=min(n/(n/i),m/(m/i));
    	res+=(phi[p]-phi[i-1])*(n/i)*(m/i)*2;
    	i=p;
    }
    printf("%lld\n",res);
    return 0;
}

φ \varphi φ的时候往往会把一些比较复杂的反演变成非常简单的筛 φ \varphi φ

推荐一些题,因为做的难度中等偏下,可能会比较水;
BZOJ2694&BZOJ4659:两道题一样的,式子推出来复杂度不够优秀不能支持多组询问,需要用的上面所说的变换下标;
BZOJ4407:同样是变换下标线性筛;
BZOJ3529:离线+树状数组;
BZOJ4816:累乘的反演,其实累乘就是在质数上相加;
LuoguP3768:本来挺复杂度反演,通过换 φ \varphi φ变成了比较水的裸杜教筛;
暂时先写那么多;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值