平常の刷题9

HHHOJ781

这题很简单,唯一值得讲的内容就是时间复杂度证明;
题目中要求我们求按位或;
那么考虑按位或,我们操作之后所得到的数,只会变得更大而不会更小,也就是说,1的位置只会变多而不会变少;那么如果1的位置的数量没有增加,那不就找到了嘛,如果增加了,他最多增加64遍,肯定要没;所以证毕;
为什么说能想到鸽巢原理,他很符合那个模型,很多东西填那么几个格子里面的模型;

HHHOJ754

狗逼题目;
不含信息理论的解法;
考虑一下结果的性质;我们发现 a a a 只能拿来 ∗ * b b b 只能拿来 + + +,所以我们可以搞一下,发现结果一定可以写成是 a x 1 + b ∗ a x 2 + b ∗ a x 3 + . . . a^{x_1} + b*a^{x_2} +b*a^{x_3} + ... ax1+bax2+bax3+... 的形式,以 a a a 为主元,我们进行降幂排列,除了前面的第一项,剩下的几项一定都是带有系数 b b b 的,然后我们就可以枚举一下把前面的第一项给除去,然后每次判断一下可不可以再除去 b b b ,后面是一串关于 a a a的多项式,可以证明无论是几都能够给草出来,证毕;

HHHOJ755

这题我又是给整了一个生硬无比的代码,看起来贼难受的那种;
首先是要找出相乘结果为完全平方数的数,然后形成了数个区间,我们应该往其中添加几个断点,使得这些区间全部都被覆盖,我选择了一个非常傻逼的方法,求出最多不相交区间数量,因为若两个区间有交点,那么我们一定可以在交点的部分搞一个断点出来切断这两个区间,虽然这样,但是这还是错的,这是没有思考证明完全的后果;
从头开始,我们发现快速判断两个数乘积是完全平方数的重要方法是:除去每个数的偶数次幂的质因子,这样就好了,剩下来的是奇数次幂的质因子即使有很多个相同的奇数次幂质因子也没有关系,因为我们只需要考虑一个数之前的那个就可以了,我不由得想起一句话,细水长流,你把当前的干好了整个就都干好了;然后第一个区间肯定是要切的,至于切哪里,肯定是最后一个,因为对于接下来的区间,右端点肯定是在这个点的右边而非是左边,所以切右边肯定是最好的,然后再来下一个没有切到的时候再来一刀即可;
其实有时候,我们处理的时候经常会考虑一下怎么更好的利用信息,却没有想到,有些时候,我们按正常思路写出来的代码,有些被我们亲手创造出来的信息或者说是约束条件,却不曾被我们给发现,利用好这些信息,是解题的关键,如何让我们创造出来的约束条件更加符合题目的内容极端重要;
下面是我贺来的代码;

#include<bits/stdc++.h>
using namespace std;
int T, n, a[200005],lst[10000005], p[10005];
bool vis[10005];
void makep() {
	for(int i=2;i<=10000;i++) if(!vis[i]) {
		p[++p[0]] = i;
		for(int j=2;i*j<=10000;j++) vis[i*j] = 1;
	}
}
inline int read() {
	int ret = 0, f=1; char ch = getchar();
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -f;
	for(;ch>='0'&&ch<='9';ch = getchar()) ret = (ret << 1) + (ret << 3) + (ch^48);
	return ret * f;
}
int main() 
{
	T = read();
	makep();
	while(T--) {
		n = read();read();int Lst = 1 , ass = 1;
		for(int i=1;i<=n;i++) {
			a[i] = read();
			for(int j=1;p[j]*p[j] <= a[i];j++)while(a[i]%(p[j]*p[j]) == 0) a[i] /= p[j]*p[j];
			if(lst[a[i]] >= Lst) ass ++ ,Lst = i;
			lst[a[i]] = i;
		}
		printf("%d\n",ass);
		for(int i=1;i<=n;i++) lst[a[i]] = 0;
	}
}

非常漂亮的一个代码,真的是非常漂亮,把我那个快2kb的能写的这么简洁;
说明作者的思路是及其清晰;

HHHOJ757

随机化,狗想得到,不过随机化随个几遍,居然能随到满分是真的离谱;

# include <bits/stdc++.h>
using namespace std;

const int maxn = 200005;

struct IO {
    static const int S = 1 << 21;
    char buf[S], * p1, * p2; int st[105], Top;
    inline char gc () { return p1 == p2 && (p2 = (p1 = buf) + fread (buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : * p1++; }
    template <typename T> inline IO & operator >> (T & x) {
        int f = 1; x = 0; char ch = gc ();
        for (;ch < '0' || ch > '9'; ch = gc ()) (ch == '-') && (f = -f);
        for (;ch >= '0' && ch <= '9'; ch = gc ()) x = (x * 10) + ch - '0';
        x *= f; return * this;
    }
} fin;

int n;
int a[maxn], x;
int b[maxn], y;

int gcd (int x, int y) {
	return x == 0 ? y : gcd (y % x, x);
}

int main () {
	fin >> n; srand (time (0));
	for (int i = 1; i <= n; i++) fin >> a[i];
	while (1.0 * clock () / CLOCKS_PER_SEC <= 0.97) { //clock per second 
		x = y = 0;
		for (int i = 1; i <= n; i++) {
			if (b[i] = (rand () & 1)) x = gcd (x, a[i]);
			else y = gcd (y, a[i]);
		}
		if (x == 1 && y == 1) {
			puts ("YES");
			for (int i = 1; i <= n; i++) printf ("%d ", b[i] + 1);
			return 0;
		}
	}
	puts ("No");
	return 0;
}

这个代码是我贺来的非常朴素的随机化;
考场中能拿七八十分估计,脸黑一点也有60分大概;

srand(time(0))
clock per second
clock() 

先考虑一种贪心思路,加入一个数 a 的时候,加入到一个 gcd 不是 a 的因子的集合,这样子 gcd 一定变小了,变得很优。
然而这肯定过不去,所以多随机几遍 a 加入的顺序,就能得到解了。
思考一下这样做的正确性,我们注意到 a 的质因子最多只有 9 个,那么什么时候我们这样子做会错误,就是其中一个集合存在一个公共质因子,而 109 以内的质数大约有 5×107 个,所以这样的概率是非常低的,于是就做完了。

这段话是正解。

HHHOJ741

这题目看起来很典型,怎么个典型法,就在于首先,他的信息只有三条,那么直接结构体集成一下,就可以搞出线性相加减的性质,这点就是这样,虽然在这题里面没什么用,但是在别的题目里面不一定没有用。然后是考虑他要你求的是相等的,他说相等的,又没说要你求一定长度的相等的有几根,这两个里面所蕴含的的数量关系是不一样的,一个所含的多了个长度的关系,因为少了条关系,我们需要面对的对象更多了,如果说直接每个对象便利过去会产生了重复的信息使用,就是说你第一个便利完之后,第二个继续遍历,相同的信息还要看一遍,这里就蕴含着一个契机,转移!信息转移利用!怎么转移,转移考虑变化量和守恒量,我们发现变化量只有一个,那么怎么找到对应的另一边的该变量,那么我们就进行一遍作差,然后排序,过滤不可能的重复信息,起飞了;

@include <bits/stdc++.h>
using namespace std;

char s[200005];
int n, res, a, b, c;
map < pair <int, int>, int > pos;

int main() {
	scanf ("%d%s", & n, s + 1);
	pos[make_pair (0, 0)] = 0;
	for (int i = 1; i <= n; i++) {
		s[i] == 'Y' ? a++ : (s[i] == 'A' ? b++ : c++);
		if (!pos.count (make_pair (a - b, b - c))) pos[make_pair (a - b, b - c)] = a;
		res = max (res, a - pos[make_pair (a - b, b - c)]);
	}
	cout << (3 * res) << endl;
	return 0;
}

这是我贺来的代码,写的非常好,比我的清晰多了;

HHHOJ742

这个题目挺恶心的,最短路,想一想,只有转移能做些文章了,因为别的地方都具有不可替代性,为什么这么说,“最短路”这个词包含了如下几个信息,短(这是相对于长而言的,具有一个数值的性质),最,什么是“短”,最短路这个算法里面的不同部分会对应着不同的以上的信息;那么题目中可以做文章的内容只有短或长和短的定义,那么求的是短的内容,然后我们就可以发现是什么是“短”的内容出现了问题,那么就考虑转移的时候改变转移方程就可以了;
考虑到改变转移方程,想到可能使用分层图,因为加上分层图之后分类讨论之后恰好可以凑满复杂度;接下来就是这个题目的难点;
难点在于他转移的内容有后效性,而且这个后效性很严重,我们甚至不能直接消除,于是考虑使用别的方法构造出一个最优子结构。然后就是这题最巧妙的一个点,将加上最小的减去最大的,看成是加上一条边和减去一条边,那么最短的路还是题目中叫我们求的那条,没有丝毫变化,这就是题目中有时候给你一条约束,你可以适量放缩,一次考虑出符合算法模型的内容;
我们思考一下,如果说将题目改为加上一条边并且删去一条边,那么我很有可能推出来原题的性质,然后就死在那里了。这启示我们,做题时,如果要套用现成的模型,应该使我们所运行处理的信息贴近模型的内容,而并非是看起来像是正解的内容;

HHHOJ743

发现每个操作最多用一次,那么35分到手了;

HHHOJ667

这个题目挺水的,其实水的原因在于模型特征非常明显,简单易懂;
考虑到最长距离,马上想到了直径,然后我们找出最长的两个点作为直径的端点,因为所有的边权都是 1 1 1 所以我们可以直接排个序,然后向下找,很简单的,发现一些细节之处需要注意,然后细节处理之后排除掉不可能的情况,照序输出就可以了,然后在这个过程中,我们发现有些时候 i m p o s s i b l e impossible impossible 的情况我们考虑不到,那么可以多造几组数据,然后对照一下我们的答案,搞一下就可以了;
有个极端数据的点没有考虑到,直接爆炸了; T M D TMD TMD

HHHOJ664

非常不明觉厉的一道题;一看就不知道怎么做,想到爆搜,结果做法是真的爆搜;
折半搜索这种东西也不是一般情况下能想到的情况,以前有一篇博客里面写到过,好处就是直接将指数化为系数;可惜我想不到;
还是贺来的,看下面理解一下这个代码;
出题人说碰到这种题可以考虑乱搞一下;

#include<bits/stdc++.h>
#define I inline
#define RI register int
#define rep(i,a,b) for(RI i=a;i<=b;++i)
#define dow(i,a,b) for(RI i=a;i>=b;--i)
using namespace std;
const int N=1000005;
int n,T,a[N],b[N];
long long p,now=-1,ans[N];
map<long long,int> mp;
I void dfs1(int u,int x,long long res,int t){
	if(u==t+1) return mp[res]=1,void();
	rep(i,x,T) if(res+ans[i]<=p) dfs1(u+1,i,res+ans[i],t);
}
I void dfs2(int u,int x,long long res,int t){
	if(u==t+1) {
		if(now==-1&&mp[p-res]){
			now=p-res;
			rep(i,1,t) printf("%d ",a[i]);
		}
		return;
	}
	rep(i,x,T) if(res+ans[i]<=p) a[u]=i,dfs2(u+1,i,res+ans[i],t),a[u]=0;
}
I void dfs3(int u,int x,long long res,int t){
	if(u==t+1){
		if(res==now){
			rep(i,1,t) printf("%d ",a[i]);
			exit(0);
		}
		return;
	}
	rep(i,x,T) if(res+ans[i]<=p) a[u]=i,dfs3(u+1,i,res+ans[i],t),a[u]=0;
}
int main(){
	scanf("%d%lld",&n,&p),ans[1]=1;
	for(T=2;T<=10000000;++T){
		long long x=1;
		for(int j=1;j<=n;++j)
			if((x*=T)>=p) break;
		if(x>=p) break;
		ans[T]=x;
	}
	--T;
	RI lmid=n>>1,rmid=n-lmid;
	dfs1(1,1,0,lmid);
	dfs2(1,1,0,rmid);
	dfs3(1,1,0,lmid);
	//整体内容大概是这样子的,第一遍搜索,尝试找到一些value,
	//第二次搜索尝试配上这些value,第三次搜索,尝试复原这些value
	//然后这题就AK了
	return 0;
}

义乌线下模拟赛

我认为这场比赛非常好,4题都是可以进行一下争取的;
可惜第二题的那个分治,我想到分治了,但是还是不太懂,然后没做出来;
等下回讲解如何想到分治的过程;

T1 美丽校园

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
我先写一下我的做法,很显然,题目翻译过来就是,求一个点,使得他的某个祖先到根节点的距离为给出的值,首先考虑暴力,发现其实暴力就是线性枚举,线性枚举可以直接优化成是一个二分,但是我们怎么知道二分出来的是那个点呢;考虑倍增枚举,我们刚好还有一些空间可以利用起来,两个log,就非常轻松的送走了这道题;
但是正解只有一个 l o g log log ,因为我没想到一个点,倍增的时候两个节点之间的间距不一定要是1;实在是大e了;这一点是正确的,可以想一下证明,举一个反例就好了;
正解代码(贺);

#include <bits/stdc++.h>
using std::reverse;
const int N = 1e5 + 10, L = 18;
int n, m, x, y, z, t, s;
int f[N][L], d[N][L], dis[N];
struct edge {
    int to, nt, vl;
    inline void init(int t, int n, int v) 
    { to = t, nt = n, vl = v; }
} e[N << 1];
int h[N], c;
inline void adde(int x, int y, int z) {
    e[++c].init(y, h[x], z), h[x] = c;
    e[++c].init(x, h[y], z), h[y] = c;
}
inline void dfs(int pos, int pnt = 0) {
    for (int i = 0; i + 1 < L && f[pos][i]; ++i) {
        f[pos][i + 1] = f[f[pos][i]][i];
        d[pos][i + 1] = d[f[pos][i]][i] + d[pos][i];
    }
    for (int i = h[pos]; i; i = e[i].nt) {
        int son = e[i].to;
        if (son == pnt)
            continue;
        d[son][0] = e[i].vl;
        f[son][0] = pos;
        dis[son] = dis[pos] + e[i].vl;
        dfs(son, pos);
    }
}
inline int getAns(int pos, int dis) {
    for (int i = L - 1; i >= 0; --i)
        if (f[pos][i] && d[pos][i] <= dis)
            dis -= d[pos][i], pos = f[pos][i];
    if (dis > 0)
        pos = f[pos][0];
    return pos;
}
int main() {
    freopen("school.in", "r", stdin);
    freopen("school.out", "w", stdout);
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n; ++i) 
    	scanf("%d%d%d", &x, &y, &z), adde(x, y, z);
    dfs(1);
    for (int i = 1; i <= m; ++i) {
        scanf("%d%d", &t, &s), s >>= 1;
        printf("%d\n", getAns(t, dis[t] - s));
    }
    return 0;
}

T2 开奶茶店

在这里插入图片描述
我是真***服了*** C S D N CSDN CSDN, 我一个题目都能被你判断成违规,你也太离谱了吧;

在这里插入图片描述
在这里插入图片描述
这个题目为什么用分治,能想到当然是因为书上那道CDQ分治的例题;
首先想到线段树平衡树,然后我发现我在想屁吃;然后想到根号数据结构,也发现自己在想屁吃,他们所维护的信息的特点都和这题没什么鸡毛关系;然后想到分治,虽然我写不来,但是可以考虑一下,想了下虽然想了个假的方法,但这些都是不那么离谱的,似乎已经接近正解的内容;
不过这次看似无用的思考,应该能为我们未来的解题带来些许启发;
没有看到写CDQ分治的,看到的都是写扫描线的;
唯一看懂的还是qy的;
就是说,我们将坐标旋转45度然后就可以开始扫描线乱杀了;请注意的是,我们虽然每个点都会有一个 d i s t a n c e distance distance 看起来好像不能离散化,但是那是取决于不同方法的,如果我们使用分治的话显然是不行的,因为我们不知道要用到什么数据每次只能在线查询,而在线查询的过程中使用离散化简直就是在想屁吃,就是拿着没有离散的跟离散过的相比较,怎么可能会得出正解呢?但是我们如果用扫描线做,我们把要查的地方也给离散进去,那么做出来的结果就是好的了;
我非常喜欢贺代码,这是我贺来的扫描线;

# include <bits/stdc++.h>
# define int long long 
using namespace std;

const int maxn = 200005;
const int maxm = 500005;
const int maxp = 900005;

struct reader {
	template <typename Type>
	reader & operator >> (Type & ret) {
		int f = 1; ret = 0; char ch = getchar ();
		for (;!isdigit (ch); ch = getchar ()) if (ch == '-') f = -f;
		for (; isdigit (ch); ch = getchar ()) ret = (ret * 10) + ch - '0';
		ret *= f; return * this;
	}
} fin;

int n, k, xxx, yyy, D;
int x[maxn], y[maxn];
int l[maxn], r[maxn];
int u[maxn], d[maxn];
int xx[maxm], lx;
int yy[maxm], ly;

struct WER {
	int x, y, val, pos;
	bool operator < (WER p) const {
		if (x != p.x) return x < p.x;
		return val ? true : false;
	}
} a[maxp]; int p;

int T[maxm];
void update (int id, int val) {
	for (; id <= ly; id += id & -id) T[id] += val;
	return ;
}
int query (int id) {
	int ret = 0;
	for (; id >= 1; id -= id & -id) ret += T[id];
	return ret;
}

int res[maxn], ans;

signed main () {
	freopen ("tea.in", "r", stdin);
	freopen ("tea.out", "w", stdout);
	fin >> n >> k;
	for (int i = 1; i <= n; i++) {
		fin >> xxx >> yyy >> D;
		xx[++lx] = x[i] = xxx - yyy; yy[++ly] = y[i] = xxx + yyy;
		xx[++lx] = l[i] = x[i] - D; xx[++lx] = r[i] = x[i] + D + 1;
		yy[++ly] = d[i] = y[i] - D; yy[++ly] = u[i] = y[i] + D + 1;
	}
	sort (xx + 1, xx + 1 + lx); lx = unique (xx + 1, xx + 1 + lx) - xx - 1;
	sort (yy + 1, yy + 1 + ly); ly = unique (yy + 1, yy + 1 + ly) - yy - 1;
	for (int i = 1; i <= n; i++) {
		x[i] = lower_bound (xx + 1, xx + 1 + lx, x[i]) - xx;
		l[i] = lower_bound (xx + 1, xx + 1 + lx, l[i]) - xx;
		r[i] = lower_bound (xx + 1, xx + 1 + lx, r[i]) - xx;
		y[i] = lower_bound (yy + 1, yy + 1 + ly, y[i]) - yy;
		d[i] = lower_bound (yy + 1, yy + 1 + ly, d[i]) - yy;
		u[i] = lower_bound (yy + 1, yy + 1 + ly, u[i]) - yy;
		a[++p] = (WER) { l[i], d[i],  1, 0 };
		a[++p] = (WER) { l[i], u[i], -1, 0 };
		a[++p] = (WER) { r[i], d[i], -1, 0 };
		a[++p] = (WER) { r[i], u[i],  1, 0 };
		a[++p] = (WER) { x[i], y[i],  0, i };
	}
	sort (a + 1, a + 1 + p);
	for (int i = 1; i <= p; i++) {
		if (a[i].val) update (a[i].y, a[i].val);
		else if (query (a[i].y) > k) res[++ans] = a[i].pos;
	}
	printf ("%lld\n", ans); sort (res + 1, res + 1 + ans);
	for (int i = 1; i <= ans; i++) printf ("%lld%c", res[i], " \n"[i == ans]);
	return 0;
}

就是这样的;

T3 病毒检测

在这里插入图片描述
在这里插入图片描述
这个题目是状压DP,但是乱搞都能过;
我直接 n e x t p e r m u t a t i o n nextpermutation nextpermutation 鲍切 85 85 85 分是我真的没有想到的;
可能是因为这个数据实在是水的太离谱了。
有人用随机化的做法直接满分了,其实这个和枚举排列的方法很是相似只不过能保证你一定是对的只不过这题目比较水。。。
发帖问了一下什么时候可以用随机化做法,得到的回答是,不得已的时候不会用随机化去做,然后随机化大部分用于数据范围比较小的,或者提答题;
然后这位大佬用一个排序吊打了我;
正解如下:
网上贺来的题解,也是爆搜,只不过是带了记忆化的爆搜,显然比我那个要好得多了;为什么说可以使用记忆化搜索呢,首先是因为是数据范围很小,应该是立马就想到要用状压DP来做的,然后有个点在于,我们要求的是全部都用完,而并非是以某种顺序来用完,所以我们只需要记录用了哪些东西就可以了,然后用了哪些东西的里面一定存在一种排列最优的,那么我们找出来不就好了嘛,就好比是我的做法,在一个个枚举排列的过程中,我应该想到一些部分是有很大的信息重复的,而这些部分可以处理出来,就是记忆化搜索。
看到另外一个用排序做的,但是讲的不清楚所以我没看懂。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = (1<<20)+5;
const int M = 30;
const int INF = 0x3f3f3f3f;
int n, c[M], dp[N][10];
void init () {
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d", &c[i]);
	memset(dp, -1, sizeof(dp));
}
int dfs (int s, int k) {
	if (dp[s][k] != -1)
		return dp[s][k];
	if (s == ((1<<n)-1))
		return k;
	int& ans = dp[s][k];
	ans = INF;
	int v[10];
	memset(v, 0, sizeof(v));
	for (int i = 0; i < n; i++) {
		if (s&(1<<i))
			continue;
		if (v[c[i]])
			continue;
		v[c[i]] = 1;
		int tmp = dfs(s^(1<<i), max(0, c[i]-k-1)) + k + 1;
		//这里面就是DP的核心内容, 每次从少掉一个的地方开始枚举,开始搜
		ans = min(ans, tmp);
	}
	return ans;
}
int main () {
	int cas;
	scanf("%d", &cas);
	while (cas--) {
		init();
		printf("%d\n", dfs(0, 0));
	}
	return 0;
}

然后,既然我们都转变为记忆化搜索了,那么再次转变为DP其实是一样的,就是通过枚举上面代码的s的状态,然后枚举出来了把它扣掉一块,比较一下哪个最优就可以了;对于DP的topo性质,其实是很好证明的;

#include<bits/stdc++.h>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int inf=1061109567;
int n,D[25],FU;
int f[1050505][16];
int main(){
	freopen("check.in","r",stdin);
	freopen("check.out","w",stdout);;
	ios::sync_with_stdio(false);
	cin>>n;FU=(1<<n)-1;
	for(int i=1;i<=n;i++)cin>>D[i];
	for(int i=1;i<=n;i++)--D[i];
	memset(f,63,sizeof(f));f[0][0]=0;
	for(register int i=1;i<=FU;i++)
	for(register int j=0,t,d;j<n;j++)if((i>>j)&1){
		t=i^(1<<j);d=D[j+1];
		for(register int k=0,w,wk;k<7;k++)
		if(f[t][k]!=inf){
			wk=max(0,d-k);w=f[t][k]+wk+1;
			f[i][wk]=min(f[i][wk],w);
		}
	}
	int ans=n*7;
	for(int i=0;i<7;i++)
	ans=min(ans,f[FU][i]);
	cout<<ans<<'\n';
	return 0;
}

这是我贺来的另外一份代码,就是DP,写得很清楚;

T3神奇老师

在这里插入图片描述

这个题目服了,别他妈写平衡树,写出来写挂了发现得分甚至不如加一个 s o r t sort sort 一遍的做法;
正解非常地简单易懂,直接上截图;
在这里插入图片描述
很清晰;不讲了,你可能看着有些信息会很难以处理但是实际上去发掘一下会发现根本没有你想象的那么难,我之前还想splay,实在是拉垮了属于是;
这题倒是跟义乌集训时候第一天讲的一道题很像, J S O I JSOI JSOI 的一个不等式,也是用不同的平衡树来维护信息的;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值