2019牛客暑期多校训练营(第二场)----J-Subarray

首先发出题目链接:
链接:https://ac.nowcoder.com/acm/contest/882/J
来源:牛客网
涉及:分治

点击这里回到2019牛客暑期多校训练营解题—目录贴


题目如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数组的长度已经被定下来了,为 1 0 9 10^9 109,此时告诉我们肯定不能直接使用前缀和

但是还有一个条件非常有用:那就是1的个数不多,而且我们知道每一段1的位置及长度

那么对于其他所有的-1,有一些-1是有用的(与其他的1或-1成为一个区间使得区间和仍然大于0),有一些-1则完全没有用,那些有用的-1和1组成的连续区间我们叫它有用区间。如图:
在这里插入图片描述

于是可以完全不考虑那些没用的-1,直接考虑所有的1和所有有用的-1,这样我们需要考虑的区间长度最多只有 1 0 7 10^7 107的长度。

还有一件事,原数组默认从0开始,然后我在输入的时候就全部加1,打算从1开始

r[0]=l[0]=0,r[n+1]=l[n+1]=1e9+1;
for(i=1;i<=n;i++){
	int a,b;
	scanf("%d%d",&a,&b);
	l[i]=a+1,r[i]=b+1;//全部加1,让数组从下标为1开始
}

对于每一段连续的1,都可以找出一段有用区间,有些有用区间可能重合或者相邻,那么这两段有用区间可以合成为一段有用区间。如图:
在这里插入图片描述
上图中对于两段全1区间,它们所对应的有用区间重合了,于是这整个一段合并成为一段有用区间。

如下图仍然是两段有用区间:
在这里插入图片描述
先将所有连续全1区间的左边界位置和右边界位置分别放在两个数组 l l l r r r

先创建两个数组 f r o n t front front b a c k back back,其中
  f r o n t [ i ] front[i] front[i]表示以第i段全1区间的右边界为右边界的最大区间和。
  b a c k [ i ] back[i] back[i]表示以第i段全1区间的左边界为左边界的最大区间和。

那么front和back数组满足两个递推式:
f r o n t [ i ] = r [ i ] − l [ i ] + 1 + m a x ( f r o n t [ i − 1 ] − ( l [ i ] − r [ i − 1 ] − 1 ) , 0 ) front[i]=r[i]-l[i]+1+max(front[i-1]-(l[i]-r[i-1]-1),0) front[i]=r[i]l[i]+1+max(front[i1](l[i]r[i1]1),0) b a c k [ j ] = r [ j ] − l [ j ] + 1 + m a x ( b a c k [ j + 1 ] − ( l [ j + 1 ] − r [ j ] − 1 ) , 0 ) back[j]=r[j]-l[j]+1+max(back[j+1]-(l[j+1]-r[j]-1),0) back[j]=r[j]l[j]+1+max(back[j+1](l[j+1]r[j]1),0)

解释一下:假设以第i段全1区间的右边界右边界的区间最大和为n ( 表 示 f r o n t [ i ] = n ) (表示front[i]=n) (front[i]=n),第i段全1区间和第i+1段中间的-1数量有m ( 表 示 l [ j + 1 ] − r [ j ] − 1 = m ) (表示l[j+1]-r[j]-1=m) (l[j+1]r[j]1=m)个。
如果 m &gt; n m&gt;n m>n,那么以第i+1段全1区间的右边界为右边界的区间最大和 ( 表 示 f r o n t [ i + 1 ] ) (表示front[i+1]) front[i+1]只能为 r [ i + 1 ] − l [ i + 1 ] + 1 r[i+1]-l[i+1]+1 r[i+1]l[i+1]+1(表示第i+1段全1区间的1的数量);
如果 m ≤ n m\le n mn,那么 f r o n t [ i + 1 ] = r [ i + 1 ] − l [ i + 1 ] + 1 + n − m front[i+1]=r[i+1]-l[i+1]+1+n-m front[i+1]=r[i+1]l[i+1]+1+nm

back[n+1]=front[0]=0;
for(i=1,j=n;i<=n && j>=1;i++,j--){
	front[i]=r[i]-l[i]+1+max(front[i-1]-(l[i]-r[i-1]-1),0);//从头到尾更新front的值
	back[j]=r[j]-l[j]+1+max(back[j+1]-(l[j+1]-r[j]-1),0);//从尾到头更新back的值
}

如果第i段有用区间和第i+1段有用区间能合并,那么满足 b a c k [ i + 1 ] + f r o n t [ i ] ≥ l [ i + 1 ] − r [ i ] − 1 back[i+1]+front[i] \ge l[i+1]-r[i]-1 back[i+1]+front[i]l[i+1]r[i]1

可以参照下图理解(图中没有标出3个全1区间的有用区间):
在这里插入图片描述
可以判断第i个有用区间往后可以合并多少有用区间,用一个数 p o s pos pos来表示,故

int pos=i;//此时遍历到第i个有用区间
while(pos<=n && front[pos]+back[pos+1]>=l[pos+1]-r[pos]-1)	pos++;//判断往后能不能继续合并后面的有用区间

合并完毕,我们就得到了真正意义上的每一段有用区间,对每一段有用区间进行求解,然后将每一段求解的答案加起来就是答案

合并之后的有用区间我们不知道他的左边界右边界的位置,它其实是类似于下面这样的区间:
在这里插入图片描述
这一段合并之后的区间我们还要看它往左和往右能延伸到什么位置,分别存到变量 f i r s t first first l a s t last last中,假设这一段合并区间跨过了第i段到第pos段的全1区间,那么:
f i r s t = m a x ( l [ i ] − b a c k [ i ] , 1 ) first=max(l[i]-back[i],1) first=max(l[i]back[i],1) l a s t = m i n ( ( i n t ) 1 e 9 , r [ p o s ] + f r o n t [ p o s ] ) last=min((int)1e9,r[pos]+front[pos]) last=min((int)1e9,r[pos]+front[pos])

解释一下:由于这一段合并区间跨过了第i段到第pos段的全1区间,于是l[i]就是合并区间中第一段全1区间的左边界,r[pos]就是合并区间中最后一段全1区间的右边界;
如果以l[i]为左边界的最大区间和为back[i],那么l[i]往左最多可以容纳back[i]个-1;
如果以r[pos]为右边界的最大区间和为front[pos],那么r[i]往右最多可以容纳front[pos]个-1;

于是这一段合并区间真正的边界就被找出来了:
在这里插入图片描述

在遍历每一个合并区间前创建一个变量ans来储存答案,对于每一段合并区间肯定是求前缀和,然后需要判断有多少对正序对即可(参考逆序对),每一段的答案加起来就是总答案。不能像求解逆序对一样用树状数组,会超时。
求合并区间前缀和代码:

		int t=i;//此合并区间第i个全1区间开始,t表示下一个未遍历到的全1区间的序号
		for(int k=first;k<=last;k++){//k从区间开始遍历到区间结尾,下面那个sum数组是合并区间的前缀和数组
			if(k>=l[t] && k<=r[t])	sum[k-first+1]=sum[k-first]+1;//遍历到某一段全1区间内,前缀和就加1
			else	sum[k-first+1]=sum[k-first]-1;//遍历到-1区间内,前缀和就加减1
			if(k==r[t])	t++;//此全1区间全部遍历完毕,t++表示该遍历第t+1个全1区间了
			cnt[sum[k-first+1]+base]=0;//这个先不管	
		}

但是我们知道由于原合并区间中只有1或者-1,所以在前缀和 s u m sum sum数组中任意两个相邻的数相差1.
并把sum[0]赋值为0.

观察上方那个合并区间的前缀数组
在这里插入图片描述
为了更好的判断正序对数量,我们创建一个数组 c n t cnt cnt c n t [ i + b a s e ] cnt[i+base] cnt[i+base]表示前缀数组 s u m sum sum中第i个数出现的次数,由于 i i i可能小于0,所以我们加一个 b a s e base base b a s e = 1 0 7 base=10^7 base=107

还要创建三个数num1和num2(初始化为0):
从sum[1]往后遍历sum数组,假设此时遍历到前缀数组的第i个(sum[i])数,那么
num2表示sum中sum[i]之前(这里包括sum[0])有多少比sum[i]小的数
num1表示sum中sum[i-1]之前(也包括sum[0])有多少比sum[i-1]小的数;

于是num1与num2就有两种关系:当此时遍历到前缀数组第i个数时(此时num1的值已经得出)
1.如果 s u m [ i ] &gt; s u m [ i − 1 ] sum[i]&gt;sum[i-1] sum[i]>sum[i1],那么 n u m 2 = n u m 1 + c n t [ s u m [ i − 1 ] + b a s e ] num2=num1+cnt[sum[i-1]+base] num2=num1+cnt[sum[i1]+base]
2.如果 s u m [ i ] &lt; s u m [ i − 1 ] sum[i]&lt;sum[i-1] sum[i]<sum[i1],那么 n u m 2 = n u m 1 + c n t [ s u m [ i ] + b a s e ] num2=num1+cnt[sum[i]+base] num2=num1+cnt[sum[i]+base]

然后num1的值加到ans中,再将num2的值赋给num1并且 c n t [ s u m [ 1 ] + b a s e ] + + cnt[sum[1]+base]++ cnt[sum[1]+base]++(表示sum[1]的个数加1),然后继续往下遍历。上面求前缀和代码中的最后一条语句其实就是在初始化

解释一下上面:
如果 s u m [ i ] &gt; s u m [ i − 1 ] sum[i]&gt;sum[i-1] sum[i]>sum[i1],那么sum[i-1]之前比sum[i-1]小的数一定都比sum[i]小,同时sum[i-1]也比sum[i]小,所以num2不仅更新为num1,还要加上sum[i-1]的个数(cnt[sum[i-1]+base]),同理 s u m [ i ] &lt; s u m [ i − 1 ] sum[i]&lt;sum[i-1] sum[i]<sum[i1]

代码:

		cnt[0+base]=1;//由于遍历从sum[1]开始,而sum[0]=0,所以开始遍历时前缀数组中0的个数就是1
		for(int k=1;k<=last-first+1;k++){//开始遍历
			if(sum[k]>sum[k-1])	num2=num1+cnt[sum[k-1]+base];//更新num2的值
			else	num2=num1-cnt[sum[k]+base];
			cnt[sum[k]+base]++;//表示sum[k]这个数又出现一次,计数
			ans+=num2;//num2表示在sum[i]前面比sum[i]小的数的个数,加入到答案中
			swap(num1,num2);//更新num1的值,继续遍历
		}

于是整个处理的代码:

	while(i<=n){
		int pos=i,t=i;
		while(pos<=n && front[pos]+back[pos+1]>=l[pos+1]-r[pos]-1)	pos++;
		ll first=(ll)max(l[i]-back[i],1),last=(ll)min((int)1e9,r[pos]+front[pos]);
		for(int k=first;k<=last;k++){//k从区间开始遍历到区间结尾,下面那个sum数组是合并区间的前缀和数组
			if(k>=l[t] && k<=r[t])	sum[k-first+1]=sum[k-first]+1;//遍历到某一段全1区间内,前缀和就加1
			else	sum[k-first+1]=sum[k-first]-1;//遍历到-1区间内,前缀和就加减1
			if(k==r[t])	t++;//此全1区间全部遍历完毕,t++表示该遍历第t+1个全1区间了
			cnt[sum[k-first+1]+base]=0;//这个先不管	
		}
		cnt[0+base]=1;//由于遍历从sum[1]开始,而sum[0]=0,所以开始遍历时前缀数组中0的个数就是1
		for(int k=1;k<=last-first+1;k++){//开始遍历
			if(sum[k]>sum[k-1])	num2=num1+cnt[sum[k-1]+base];//更新num2的值
			else	num2=num1-cnt[sum[k]+base];
			cnt[sum[k]+base]++;//表示sum[k]这个数又出现一次,计数
			ans+=num2;//num2表示在sum[i]前面比sum[i]小的数的个数,加入到答案中
			swap(num1,num2);//更新num1的值,继续遍历
		}
		i=pos+1;
	}

举个例子(可以忽略):

输入:

2
0 1
3 4

代表的整个数组为
在这里插入图片描述
先算 f r o n t front front b a c k back back数组
f r o n t [ 1 ] = r [ 1 ] − l [ 1 ] + 1 + m a x ( f r o n t [ 0 ] − ( l [ 1 ] − r [ 0 ] − 1 ) , 0 ) front[1]=r[1]-l[1]+1+max(front[0]-(l[1]-r[0]-1),0) front[1]=r[1]l[1]+1+max(front[0](l[1]r[0]1),0)
= 2 − 1 + 1 + m a x ( 0 − ( 1 − 0 − 1 ) , 0 ) = 2 =2-1+1+max(0-(1-0-1),0)=2 =21+1+max(0(101),0)=2

f r o n t [ 2 ] = r [ 2 ] − l [ 2 ] + 1 + m a x ( f r o n t [ 1 ] − ( l [ 2 ] − r [ 1 ] − 1 ) , 0 ) front[2]=r[2]-l[2]+1+max(front[1]-(l[2]-r[1]-1),0) front[2]=r[2]l[2]+1+max(front[1](l[2]r[1]1),0)
= 5 − 4 + 1 + m a x ( 2 − ( 4 − 2 − 1 ) , 0 ) = 3 =5-4+1+max(2-(4-2-1),0)=3 =54+1+max(2(421),0)=3

b a c k [ 2 ] = r [ 2 ] − l [ 2 ] + 1 + m a x ( b a c k [ 3 ] − ( l [ 3 ] − r [ 2 ] − 1 ) , 0 ) back[2]=r[2]-l[2]+1+max(back[3]-(l[3]-r[2]-1),0) back[2]=r[2]l[2]+1+max(back[3](l[3]r[2]1),0)
= 5 − 4 + 1 + m a x ( 0 − ( 1 0 9 − 5 − 1 ) , 0 ) = 2 =5-4+1+max(0-(10^9-5-1),0)=2 =54+1+max(0(10951),0)=2

b a c k [ 1 ] = r [ 1 ] − l [ 1 ] + 1 + m a x ( b a c k [ 2 ] − ( l [ 2 ] − r [ 1 ] − 1 ) , 0 ) back[1]=r[1]-l[1]+1+max(back[2]-(l[2]-r[1]-1),0) back[1]=r[1]l[1]+1+max(back[2](l[2]r[1]1),0)
= 2 − 1 + 1 + m a x ( 2 − ( 4 − 2 − 1 ) , 0 ) = 3 =2-1+1+max(2-(4-2-1),0)=3 =21+1+max(2(421),0)=3

由于 b a c k [ 2 ] + f r o n t [ 1 ] &gt; l [ 2 ] − r [ 1 ] − 1 back[2]+front[1]&gt;l[2]-r[1]-1 back[2]+front[1]>l[2]r[1]1,故两个区间可以合并。

f i r s t = m a x ( ( l [ 1 ] − b a c k [ 1 ] ) , 1 ) = m a x ( ( 1 − 3 ) , 0 ) = 1 first=max((l[1]-back[1]),1)=max((1-3),0)=1 first=max((l[1]back[1]),1)=max((13),0)=1
l a s t = m i n ( ( r [ 2 ] + f r o n t [ 2 ] ) , 1 0 9 ) = m i n ( ( 5 + 3 ) , 1 0 9 ) = 8 last=min((r[2]+front[2]),10^9)=min((5+3),10^9)=8 last=min((r[2]+front[2]),109)=min((5+3),109)=8

表面有用区间范围为 [ 1 , 8 ] [1,8] [1,8]

算出前缀和,遍历前缀和
在这里插入图片描述
1.遍历到 s u m [ 1 ] , s u m [ 1 ] &gt; s u m [ 0 ] sum[1],sum[1]&gt;sum[0] sum[1]sum[1]>sum[0],故
n u m 2 = n u m 1 + c n t [ s u m [ 0 ] + b a s e ] = 0 + c n t [ 0 + b a s e ] = 1 num2=num1+cnt[sum[0]+base]=0+cnt[0+base]=1 num2=num1+cnt[sum[0]+base]=0+cnt[0+base]=1
c n t [ s u m [ 1 ] + b a s e ] + + cnt[sum[1]+base]++ cnt[sum[1]+base]++,记录答案将num2赋给num1
在这里插入图片描述

2.遍历到 s u m [ 2 ] , s u m [ 2 ] &gt; s u m [ 1 ] sum[2],sum[2]&gt;sum[1] sum[2]sum[2]>sum[1],故
n u m 2 = n u m 1 + c n t [ s u m [ 1 ] + b a s e ] = 1 + c n t [ 1 + b a s e ] = 2 num2=num1+cnt[sum[1]+base]=1+cnt[1+base]=2 num2=num1+cnt[sum[1]+base]=1+cnt[1+base]=2
c n t [ s u m [ 2 ] + b a s e ] + + cnt[sum[2]+base]++ cnt[sum[2]+base]++,记录答案将num2赋给num1
在这里插入图片描述

3.遍历到 s u m [ 3 ] , s u m [ 3 ] &lt; s u m [ 2 ] sum[3],sum[3]&lt;sum[2] sum[3]sum[3]<sum[2],故
n u m 2 = n u m 1 − c n t [ s u m [ 3 ] + b a s e ] = 2 − c n t [ 1 + b a s e ] = 1 num2=num1-cnt[sum[3]+base]=2-cnt[1+base]=1 num2=num1cnt[sum[3]+base]=2cnt[1+base]=1
c n t [ s u m [ 3 ] + b a s e ] + + cnt[sum[3]+base]++ cnt[sum[3]+base]++,记录答案将num2赋给num1
在这里插入图片描述

4.遍历到 s u m [ 4 ] , s u m [ 4 ] &gt; s u m [ 3 ] sum[4],sum[4]&gt;sum[3] sum[4]sum[4]>sum[3],故
n u m 2 = n u m 1 + c n t [ s u m [ 3 ] + b a s e ] = 1 + c n t [ 1 + b a s e ] = 3 num2=num1+cnt[sum[3]+base]=1+cnt[1+base]=3 num2=num1+cnt[sum[3]+base]=1+cnt[1+base]=3
c n t [ s u m [ 4 ] + b a s e ] + + cnt[sum[4]+base]++ cnt[sum[4]+base]++,记录答案将num2赋给num1
在这里插入图片描述

5.遍历到 s u m [ 5 ] , s u m [ 5 ] &gt; s u m [ 4 ] sum[5],sum[5]&gt;sum[4] sum[5]sum[5]>sum[4],故
n u m 2 = n u m 1 + c n t [ s u m [ 4 ] + b a s e ] = 3 + c n t [ 2 + b a s e ] = 5 num2=num1+cnt[sum[4]+base]=3+cnt[2+base]=5 num2=num1+cnt[sum[4]+base]=3+cnt[2+base]=5
c n t [ s u m [ 5 ] + b a s e ] + + cnt[sum[5]+base]++ cnt[sum[5]+base]++,记录答案将num2赋给num1
在这里插入图片描述

6.遍历到 s u m [ 6 ] , s u m [ 6 ] &lt; s u m [ 5 ] sum[6],sum[6]&lt;sum[5] sum[6]sum[6]<sum[5],故
n u m 2 = n u m 1 − c n t [ s u m [ 6 ] + b a s e ] = 5 − c n t [ 2 + b a s e ] = 3 num2=num1-cnt[sum[6]+base]=5-cnt[2+base]=3 num2=num1cnt[sum[6]+base]=5cnt[2+base]=3
c n t [ s u m [ 6 ] + b a s e ] + + cnt[sum[6]+base]++ cnt[sum[6]+base]++,记录答案将num2赋给num1
在这里插入图片描述

7.遍历到 s u m [ 7 ] , s u m [ 7 ] &lt; s u m [ 6 ] sum[7],sum[7]&lt;sum[6] sum[7]sum[7]<sum[6],故
n u m 2 = n u m 1 − c n t [ s u m [ 7 ] + b a s e ] = 3 − c n t [ 1 + b a s e ] = 1 num2=num1-cnt[sum[7]+base]=3-cnt[1+base]=1 num2=num1cnt[sum[7]+base]=3cnt[1+base]=1
c n t [ s u m [ 7 ] + b a s e ] + + cnt[sum[7]+base]++ cnt[sum[7]+base]++,记录答案将num2赋给num1
在这里插入图片描述

8.遍历到 s u m [ 8 ] , s u m [ 8 ] &lt; s u m [ 7 ] sum[8],sum[8]&lt;sum[7] sum[8]sum[8]<sum[7],故
n u m 2 = n u m 1 − c n t [ s u m [ 8 ] + b a s e ] = 1 − c n t [ 0 + b a s e ] = 0 num2=num1-cnt[sum[8]+base]=1-cnt[0+base]=0 num2=num1cnt[sum[8]+base]=1cnt[0+base]=0
c n t [ s u m [ 8 ] + b a s e ] + + cnt[sum[8]+base]++ cnt[sum[8]+base]++,记录答案将num2赋给num1
在这里插入图片描述

遍历完毕
a n s = 1 + 2 + 1 + 3 + 5 + 3 + 1 = 16 ans=1+2+1+3+5+3+1=16 ans=1+2+1+3+5+3+1=16


代码如下:

#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
const int maxm=1e7+5;
int n;//题目所给变量
int l[maxn],r[maxn],back[maxn],front[maxn];//l[i],r[i]表示第i段全1区间的左右边界;
//front[i]表示以第i段全1区间的右边界为右边界的区间和最大值,back[i]表示以第i段全1区间的左边界为左边界的区间和最大值
int cnt[3*maxm],num1=0,num2=0; //cnt[i+base]表示i在前缀和数组中出现的次数
//num1表示sum中在sum[i-1]之前(也包括sum[0])有多少比sum[i-1]小的数;
//num2表示sum中在sum[i]之前(这里包括sum[0])有多少比sum[i]小的数;
int sum[3*maxm]={0};//sum是前缀和数组
ll ans=0;//答案
int main(){
	scanf("%d",&n);
	int i,j;
	back[n+1]=front[0]=r[0]=l[0]=0,r[n+1]=l[n+1]=1e9+1;//初始化某些值
	for(i=1;i<=n;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		l[i]=a+1,r[i]=b+1;//全部加1,让数组从下标为1开始
	}
	for(i=1,j=n;i<=n && j>=1;i++,j--){
		front[i]=r[i]-l[i]+1+max(front[i-1]-(l[i]-r[i-1]-1),0);//从头到尾更新front的值
		back[j]=r[j]-l[j]+1+max(back[j+1]-(l[j+1]-r[j]-1),0);//从尾到头更新back的值
	}
	i=1;//i指第i段全1区间,初始化为1
	int base=1e7+1;//base防止cnt数组的下标为负数
	while(i<=n){//遍历每一段全1区间
		int pos=i,t=i;//pos指当前全1区间所扩展成的有用区间中的第一段全1区间的序号,t表示下一个未遍历到的全1区间的序号
		while(pos<=n && front[pos]+back[pos+1]>=l[pos+1]-r[pos]-1)	pos++;//判断当前全1区间能往后延伸合并到哪一个全1区间
		ll first=(ll)max(l[i]-back[i],1),last=(ll)min((int)1e9,r[pos]+front[pos]);//first和last表示当前合并后的有用区间的左右位置
		for(int k=first;k<=last;k++){//k从区间开始遍历到区间结尾,下面那个sum数组是合并区间的前缀和数组
			if(k>=l[t] && k<=r[t])	sum[k-first+1]=sum[k-first]+1;//遍历到某一段全1区间内,前缀和就加1
			else	sum[k-first+1]=sum[k-first]-1;//遍历到-1区间内,前缀和就加减1
			if(k==r[t])	t++;//此全1区间全部遍历完毕,t++表示该遍历第t+1个全1区间了
			cnt[sum[k-first+1]+base]=0;	//初始化cnt数组
		}
		cnt[0+base]=1;//由于遍历从sum[1]开始,而sum[0]=0,所以开始遍历时前缀数组中0的个数就是1
		for(int k=1;k<=last-first+1;k++){//开始遍历
			if(sum[k]>sum[k-1])	num2=num1+cnt[sum[k-1]+base];//更新num2的值
			else	num2=num1-cnt[sum[k]+base];
			cnt[sum[k]+base]++;//表示sum[k]这个数又出现一次,计数
			ans+=num2;//num2表示在sum[i]前面比sum[i]小的数的个数,加入到答案中
			swap(num1,num2);//更新num1的值,继续遍历
		}
		i=pos+1;//由于当前合并后的有用区间已经包括了第i段到第pos段的全1区间,已经不需要重复考虑了,下一次直接考虑第pos+1段全1区间
	}
	printf("%lld",ans);//输出答案
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值