Codeforces Round 893 div 2 A-E2 个人练习

A. Buttons

题意:
A l i c e Alice Alice B o b Bob Bob 在玩一个游戏,有三种按钮,其中 a a a 按钮只能被 A l i c e Alice Alice 按, b b b 按钮只能被 B o b Bob Bob
c c c 按钮两个人都可以按,每个按钮只能被按一次,两个人轮流按,每次只能按一个
如果轮到这个人按,但是他没有可以按的按钮了,那么他就输
判断谁是赢家

思路:
两个人肯定优先按 c c c 类按钮,然后才按自己的那一类按钮,判断一下数量就可以

// Problem: Buttons
// Contest: Codeforces
// URL: https://m1.codeforces.com/contest/1858/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 

const int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;

typedef long long ll;

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int t;
    std::cin>>t;
    while(t--){
    	ll a,b,c;
    	std::cin>>a>>b>>c;
    	ll x1=a+(c&1);	//如果c是奇数 A比B多拿一个c  否则两人那的c按钮一样多
    	ll x2=b;
    	std::cout<<(x1>x2?"First":"Second")<<endl;
    }
	return 0; 
}

B. The Walkway

题意:
n n n 个海滩, m m m 个售卖店分布在其中一些海滩,第 i i i 个售卖店在第 s i s_i si 个海滩
P e t y a Petya Petya 从第一个海滩按顺序走向最后一个海滩,如果至少符合以下一个条件, P e t y a Petya Petya 会吃一块饼干:

  • 在第 i i i 个海滩有一个售卖店,他会买一块饼干并吃掉
  • 他在第一个海滩会直接吃掉一块饼干
  • 距离上次吃饼干的海滩到现在,已经有 d d d 个海滩没吃饼干了,他会在这个海滩吃下一块。
    例如 d = 2 d=2 d=2 ,上次在 2 e d 2ed 2ed 海滩吃了饼干, 3 3 3 号没吃,那么在 4 4 4 号会吃下一块饼干

P e t y a Petya Petya 在每个海滩最多吃下一个饼干,现在要移走其中一个售卖店,要求最后他吃的饼干最少
求出他最后最少吃多少块饼干,并给出相应的移走售卖店的方案数

思路:
题意比较复杂,但是其实就是简单预处理一下一个售卖店都不移走的话,能吃多少块饼干

因为假如移走的是第 i i i 号售卖店,它只会影响 i − 1 i-1 i1 i + 1 i+1 i+1 号售卖店这段区间吃的饼干
其余区间吃饼干的活动并不会被干扰!

因此我们可以直接枚举这个移走的店就可以,同时统计一下方案数

要注意一些edge case例如第一间店在 1 1 1 或者最后一间店在 n n n

// Problem: The Walkway
// Contest: Codeforces
// URL: https://m1.codeforces.com/contest/1858/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 

const int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;

typedef long long ll;

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int t;
    std::cin>>t;
    while(t--){
    	int n,m,d;
    	std::cin>>n>>m>>d;
    	std::vector<int> a(m+5);	//售卖店坐标
    	a[0]=1;
    	a[m+1]=n;
    	fore(i,1,m+1)	std::cin>>a[i];
    	int ans=INF,cnt=1;	//吃掉的饼干数和方案数
    	int x=1;	//在1号吃的饼干
    	if(a[1]==1)	x=0;	//如果1号就有一个店,就撤销这个,后面算每个店吃的饼干再加上去
    	fore(i,1,m+1){	//预处理一个店都不移走吃的饼干
    		++x;
    		x+=(a[i]-a[i-1]-1)/d;
    	}
    	x+=(n-a[m])/d;	//最后一个店到n点这一段
    	fore(i,1,m+1){
    		int res=0;
    		if(i==1){
    			res+=x-1;
    			if(a[1]>1)	res-=(a[1]-2)/d;
    			else ++res;
    			res-=(a[i+1]-a[i]-1)/d;
    			res+=(a[i+1]-2)/d;
    		}
    		else if(i==m){
    			res+=x-1;
    			res-=(a[i]-a[i-1]-1)/d;
    			if(a[i]<n)	res-=(n-a[i])/d;
    			res+=(n-a[i-1])/d;
    		}
    		else res=x-1-(a[i+1]-a[i]-1)/d-(a[i]-a[i-1]-1)/d+(a[i+1]-a[i-1]-1)/d;
    		if(res<ans){
    			ans=res;
    			cnt=1;
    		}
    		else if(res==ans)	++cnt;
    	}
    	std::cout<<ans<<' '<<cnt<<endl;
    }
	return 0; 
}

C. Yet Another Permutation Problem

题意:
对于一个长度为 n n n 的排列 a 1 , a 2 . . . a n a_1,a_2...a_n a1,a2...an,定义 d i = g c d ( a i , a ( ( i m o d n ) + 1 ) d_i = gcd(a_i,a_{((i\hspace{2pt}mod\hspace{2pt}n)+1}) di=gcd(ai,a((imodn)+1)
定义 s c o r e score score d i d_i di 里面不同数的个数

给出 s c o r e score score 最高的长度为 n n n 的排列

思路:
首先, d i d_i di 一定 ≤ ⌊ n 2 ⌋ \leq \lfloor \dfrac{n}{2} \rfloor 2n ,因此对于一个长度为 n n n 的排列,最大的 s c o r e score score 就是 ⌊ n 2 ⌋ \lfloor \dfrac{n}{2} \rfloor 2n d i ∈ [ 1 , ⌊ n 2 ⌋ ] d_i \in [1,\lfloor \dfrac{n}{2} \rfloor] di[1,2n⌋]

只需要对每个 d i d_i di 后面跟一个 2 d i 2d_i 2di 就可以构造出 d i = g c d ( d i , 2 d i ) d_i = gcd(d_i , 2d_i) di=gcd(di,2di)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 

const int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;

typedef long long ll;

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int t;
    std::cin>>t;
    while(t--){
    	int n;
    	std::cin>>n;
    	for(int i=1;i<=n;i+=2)
    		for(int j=i;j<=n;j<<=1)
    			std::cout<<j<<' ';
    	std::cout<<endl;
    }
	return 0; 
}

D. Trees and Segments

题意:
给定一个长度为 n n n 01 01 01 s s s,定义 l 0 、 l r l_0、l_r l0lr

  • l 0 l_0 l0 是最大连续 0 0 0 的数量
  • l 1 l_1 l1 是最大连续 1 1 1 的数量

对于一个正整数 a a a ,定义 b e a u t y beauty beauty

  • b e a u t y = a ⋅ l 0 + l 1 beauty = a \cdot l_0 + l_1 beauty=al0+l1

你最多可以修改 k k k s s s 中的字符,求出 a ∈ [ 1 , n ] a \in [1,n] a[1,n] 各自对应的最大 b e a u t y beauty beauty

思路:
如果对于每一个 a a a ,我们枚举 l 1 l_1 l1 的长度,可以得到这个 l 1 l_1 l1 对应的 l 0 l_0 l0 的话,就是这个 a a a 的答案
这里时间复杂度是 O ( n 2 ) O(n^2) O(n2)

问题就转化为:求 l 1 ∈ [ 1 , n ] l_1 \in [1,n] l1[1,n] 对应的最大 l 0 l_0 l0
不难发现:对于一段长度为 l 1 l_1 l1 的连续 1 1 1 区间,两边肯定都是 0 0 0 ,否则 l 1 l_1 l1 肯定会更大
因此 l 0 l_0 l0 一定在 l 1 l_1 l1 的左边或者右边,问题是如何快速求出这个 l 0 l_0 l0

考虑 D P DP DP
定义 p r e [ i ] [ j ] pre[i][j] pre[i][j] 为前缀 1 → i 1\rightarrow i 1i 最多 修改 j j j并且 最长 0 0 0 i i i 结束的最大 l 0 l_0 l0,那么它的转移方程可以写成这样:

p r e [ i ] [ j ] = { p r e [ i − 1 ] [ j ] + 1 , i f : s [ i ] = 0 p r e [ i − 1 ] [ j − 1 ] + 1 , i f : s [ i ] = 1 a n d j > 0 0 , o t h e r w i s e pre[i][j]= \begin{cases} pre[i-1][j] + 1 \quad, if: \quad s[i]=0 \\\\ pre[i-1][j-1] + 1 \quad, if: \quad s[i]=1 \quad and \quad j>0\\\\ 0, \quad otherwise \end{cases} pre[i][j]= pre[i1][j]+1,if:s[i]=0pre[i1][j1]+1,if:s[i]=1andj>00,otherwise

第一种情况是直接把 0 0 0 拼接上去,第二种情况是 1 1 1 改成 0 0 0,第三种情况就是没有操作数了

这样子得出来的局限是 必须在 i i i 位置结束 ,我们可以将前缀向后传递,取 m a x max max
这样就可以将 p r e [ i ] [ j ] pre[i][j] pre[i][j] 转化为前缀 1 → i 1\rightarrow i 1i 区间最多操作 j j j 次的最大 l 0 l_0 l0 ,且不限制结束位置

类似地可以定义 s u f suf suf 后缀,这样就可以对于一段长度为 l 1 l_1 l1 的区间快速求出两边的 m a x l 0 max \hspace{2pt}l_0 maxl0

枚举连续 1 1 1 区间,算出里面原来 0 0 0 的个数 x x x,把 0 0 0 全部转化成 1 1 1 ,然后求出剩余操作数 k − x k-x kx 可以在两边得到的最大 l 0 l_0 l0,记录一下即可

注意要算 l 1 = 0 l_1 = 0 l1=0 的情况

// Problem: D. Trees and Segments
// Contest: Codeforces - Codeforces Round 893 (Div. 2)
// URL: https://codeforces.com/contest/1858/problem/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 

const int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;

typedef long long ll;

void solve(){
	int n,k;
	std::cin>>n>>k;
	std::string s;
	std::cin>>s;
	s='0'+s;	//让下标从1开始
	std::vector<std::vector<ll>> pre(n+2,std::vector<ll>(n+2,0));
	std::vector<std::vector<ll>> suf(n+2,std::vector<ll>(n+2,0));
	std::vector<ll> ans(n+1,0);
	std::vector<ll> dp(n+1,-1000000);	//连续'1'的长度为i时,对应的最大'0'长度
	
	fore(i,1,n+1)	//计算前缀
		fore(j,0,k+1){
			if(s[i]=='0')	pre[i][j]=std::min(pre[i-1][j]+1,1ll*i);
			else if(s[i]=='1' && j>0)	pre[i][j]=std::min(pre[i-1][j-1]+1,1ll*i);
			else pre[i][j]=0;
		}
	for(int i=n;i>=1;--i)	//计算后缀
		fore(j,0,k+1){
			if(s[i]=='0')	suf[i][j]=std::min(suf[i+1][j]+1,1ll*n-i+1);
			else if(s[i]=='1' && j>0)	suf[i][j]=std::min(suf[i+1][j-1]+1,1ll*n-i+1);
			else suf[i][j]=0;	
		}
		
	fore(i,1,n+1)	//前缀向后传递
		fore(j,0,k+1){
			if(i>0)	pre[i][j]=std::max(pre[i][j],pre[i-1][j]);
			if(j>0)	pre[i][j]=std::max(pre[i][j],pre[i][j-1]);
		}
	for(int i=n;i>=1;--i)	//后缀向前传递
		fore(j,0,k+1){
			if(i<n)	suf[i][j]=std::max(suf[i][j],suf[i+1][j]);
			if(j>0)	suf[i][j]=std::max(suf[i][j],suf[i][j-1]);
		}
		
	fore(l,1,n+1){
		int x=0;	//把这段区间全部变为'1' 需要的操作数
		fore(r,l,n+1){
			x+=(s[r]=='0');
			if(k<x)	break;
			int len=r-l+1;
			dp[len]=std::max({dp[len],pre[l-1][k-x],suf[r+1][k-x]});
		}
		dp[0]=std::max({dp[0],pre[l][k],suf[l][k]}); //L1=0的情况
	}
	
	fore(a,1,n+1)
		fore(len,0,n+1){	//枚举 L1
			ans[a]=std::max(ans[a],len+1ll*a*dp[len]);
		}
	
	fore(i,1,n+1)	std::cout<<ans[i]<<" \n"[i==n];
}

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int t;
    std::cin>>t;
    while(t--){
    	solve();
    }
	return 0; 
}

E1/E2. Rollbacks

这两题 e a s y v e r s i o n easy\hspace{2pt}version easyversion h a r d v e r s i o n hard\hspace{2pt}version hardversion 的区别就是 E 1 E1 E1 可以离线,而 E 2 E2 E2 强制在线

题意:
数组 a a a 初始为空,有四种操作:

  • + x +\quad x +x,将 x x x 添加到 a a a 的末尾
  • − k - \quad k k,移除 a a a 的最后 k k k 个数
  • ! ! ! ,撤销上一个操作一操作二
  • ? ? ?,输出现在 a a a 里面有多少个不同的数

思路:
这题的做法是学习借鉴 jiangly 的代码和思路,有 q l o g q qlogq qlogq 的做法也有线性的做法

先考虑操作1和操作2,我们定义 p o s [ i ] pos[i] pos[i] i i i 第一次出现的下标,如果是第一次出现,那么从这个位置开始往后的每一位,答案都要 + 1 +1 +1,最后询问答案就是 t r e e [ n ] tree[n] tree[n] 的值, n n n 就是现在数组 a a a 里面的元素个数

考虑树状数组来完成这个单点修改,区间查询的操作

如果是第一次出现,从这个位置开始一直到 t r e e tree tree 数组的末尾,全部 + 1 +1 +1
操作二的话直接 n − = k n-=k n=k 就可以了,因为这样就又回到了 k k k 个数之前的 t r e e tree tree

现在考虑操作三的撤销,如果是撤销操作二的话,直接 n + = k n+=k n+=k 就可以,因为最后一次操作是操作二,意味着 t r e e tree tree 数组没有被修改
如果是撤销操作一 的话,要考虑数组 a a a 现在这个位置的值 x x x ,和这个位置之前的值 z z z
因为操作一添加一个数 x x x 的话,这个位置可能以前就有添加过一个数 z z z z z z 可能在 t r e e tree tree 留下了它第一次出现的贡献,所以要先减去 z z z 的贡献,然后再考虑 x x x 是否第一次出现,是否需要区间修改

基于这个准则,我们撤销操作一,也应该要把现在的数 x x x 的贡献看看要不要去掉(如果它是第一次出现的话),还要把之前的数 z z z 的贡献给加上(如果 z z z 是在这个位置第一次出现的话)那么怎么判断这两个数是否第一次出现?

jiangly 的做法非常天才,他先把这个要添加的新的 x x x 以及他现在的第一次出现的位置 p o s [ x ] pos[x] pos[x] 、还有这个位置之前的数 z z z 以及 p o s [ z ] pos[z] pos[z] 插入到一个 o p t opt opt 数组中,用来记录所有的操作一和操作二,方便后面撤销

注意这个时候插入 o p t opt opt p o s [ x ] pos[x] pos[x] p o s [ z ] pos[z] pos[z] 都是旧值,对于他们的更新是插入完后才更新的
如果 p o s [ z ] = = n pos[z]==n pos[z]==n ,也就是说 n n n 这个位置是 z z z 的第一次出现的位置,现在把它的贡献删掉,并把 p o s [ z ] pos[z] pos[z] 设置为无穷大 ( q + 1 ) (q+1) (q+1) ,同理,如果 p o s [ x ] > n pos[x]>n pos[x]>n ,说明现在数组里 x x x 是第一次出现,要把 x x x之前位置的贡献删掉,在 n n n 这个位置加上新贡献,并把 p o s [ x ] pos[x] pos[x] 设置为 n n n

看到这里,不难想到,撤销时,如果发现一个数 x x x p o s pos pos 值和现在 p o s pos pos 值不一样的话,这个数的贡献一定被修改过了,现在要撤销这个修改就很容易了,直接把现在的贡献减掉,把之前的贡献加回去就可以了

对于这个位置的值 z z z 也是同样的道理

树状数组做法:
时间复杂度: O ( q l o g q ) O(qlogq) O(qlogq)

// Problem: E1. Rollbacks (Easy Version)
// Contest: Codeforces - Codeforces Round 893 (Div. 2)
// URL: https://codeforces.com/contest/1858/problem/E1
// Memory Limit: 256 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 
#define lowbit(x)	((x)&-(x))

const int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;

typedef long long ll;

const int N=1000050;
int a[N];	//a数组及里面的数字

struct Fenwick{
	int n;
	std::vector<int> tree;
	
	Fenwick(int n){
		this->n=n;
		tree.assign(n,0);
	}
	
	void update(int x,int d){
		while(x<n){
			tree[x]+=d;
			x+=lowbit(x);
		}
	}
	
	int sum(int x){
		int res=0;
		while(x>0){
			res+=tree[x];
			x-=lowbit(x);
		}
		return res;
	}
};

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int q;
    int n=0;	//不初始化喜提两发RE
    std::cin>>q;
    Fenwick fen(q+5);
    std::vector<std::array<int,4>> opt;
    std::vector<int> pos(N,q+1);
    fore(i,1,q+1){
    	char c;
    	std::cin>>c;
    	if(c=='+'){
    		int x;
    		std::cin>>x;
    		++n;
    		opt.push_back({x,pos[x],a[n],pos[a[n]]});	//先把旧值保留
    		if(pos[a[n]]==n){	//之前残留的元素刚好在这个位置第一次出现
    			fen.update(n,-1);	//要维护后面的tree
    			pos[a[n]]=q+1;
    			fen.update(q+1,1);
    		}
    		if(pos[x]>n){	//fist appearance
    			fen.update(pos[x],-1);
    			pos[x]=n;
    			fen.update(n,1);
    		}
    		a[n]=x;
    	}
    	else if(c=='-'){
    		int k;
    		std::cin>>k;
    		n-=k;
    		opt.push_back({-1,k});
    	}
    	else if(c=='?'){
    		std::cout<<fen.sum(n)<<endl;
    		//std::cout.flush();  E2要加上这一句来刷新,不然读入不了后面的操作
    	}
    	else{
    		auto [x,y,z,w]=opt.back();
    		opt.pop_back();
    		if(x==-1)	n+=y;	//'-'操作复原
    		else{
    			if(y!=pos[x]){	//y是旧值  如果跟现在的pos不一样,一定是修改过
    				fen.update(pos[x],-1);
    				pos[x]=y;
    				fen.update(y,1);
    			}
    			if(w!=pos[z]){	//w是旧值
    				fen.update(pos[z],-1);
    				pos[z]=w;
    				fen.update(w,1);
    			}
    			a[n]=z;
    			--n;
    		}
    	}
    }
	return 0; 
}

赛后 jiangly 又指出这题可以使用线性做法过掉

其实就是把树状数组的单点修改改成了差分前缀和,用这两个来维护答案

因为假如现在加到了 n n n 个数,询问的话也最多问到 n n n,不会询问到 n n n 后面的答案
所以我们可以将树状数组的单点修改,改成在差分数组上的修改,后面继续添加新的数字的时候,加上差分数组记录的贡献就可以

但是这种做法要注意先加了几个数,然后删掉 k k k 个数后,又加了几个数,最后一直撤销到删除 k k k 个数之前
h a c k hack hack 数据 (输出应该是 3 3 3):

10
+ 1
+ 2
+ 3
- 2
+ 1
+ 2
!
!
!
?

这种操作方法的话,最后询问的 s u n [ n ] sun[n] sun[n] 可能已经被修改了,而且 s u m [ n − 1 ] sum[n-1] sum[n1] 很有可能在删除了 k k k 个数之后,加上新的一些数的时候被更新了,因此现在撤销的话不能直接 s u m [ n ] = s u m [ n − 1 ] + d [ n ] sum[n] = sum[n-1] +d[n] sum[n]=sum[n1]+d[n] 来算
必须在添加新的数的时候把 s u m sum sum 值插入到 o p t opt opt 数组中,撤销的时候直接赋值,这样就可以保证正确性

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n' 

const int INF=0x3f3f3f3f;
const long long INFLL=0x3f3f3f3f3f3f3f3fLL;

typedef long long ll;

const int N=1000050;
int a[N];

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    int q;
    std::cin>>q;
    std::vector<int> pos(N,q+1);
    std::vector<std::array<int,5>> opt;
    std::vector<int> sum(q+1,0);	//前缀和
    std::vector<int> d(q+5,0);	//差分数组
    int n=0;
    fore(i,1,q+1){
    	char c;
    	std::cin>>c;
    	if(c=='+'){
    		int x;
    		std::cin>>x;
    		++n;
    		opt.push_back({x,pos[x],a[n],pos[a[n]],sum[n]});
    		if(pos[a[n]]==n){
    			--d[n];
    			pos[a[n]]=q+1;
    			++d[q+1];
    		}
    		if(pos[x]>n){
    			--d[pos[x]];
    			pos[x]=n;
    			++d[n];
    		}
    		sum[n]=sum[n-1]+d[n];
    		a[n]=x;
    	}
    	else if(c=='-'){
    		int k;
    		std::cin>>k;
    		n-=k;
    		opt.push_back({-1,k});
    	}
    	else if(c=='?'){
    		std::cout<<sum[n]<<endl;
    		std::cout.flush();
    	}
    	else{
    		auto [x,y,z,w,t]=opt.back();
    		opt.pop_back();
    		if(x==-1)	n+=y;
    		else{
    			sum[n]=t;	//必须储存旧值 因为sum[n-1]可能已经改变,不是旧的sum[n-1]
    			if(y!=pos[x]){
    				--d[pos[x]];
    				pos[x]=y;
    				++d[y];
    			}
    			if(w!=pos[z]){
    				--d[pos[z]];
    				pos[z]=w;
    				++d[w];
    			}
    			a[n--]=z;
    		}
    	}
    }
	return 0; 
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值