模板综合1

部分算法模板(难度:未知~普及-)

前言:部分自己打的,部分是题解(毕竟我的码风太丑)。不确保所有模板的正确性——以后会一个个试的。

1.高精度 || 难度:普及-

(1)高精度加法

题意:求A+B

#include<cstdio>
#include<cstring>
#define MAX 500
char str[MAX];
int c[MAX],a[MAX],b[MAX],lena,lenb,len,i;
int main(){
    /*这一部分,从第10行至第23行,为倒置存入的过程*/
    /*输入第一个加数*/
    scanf("%s",str);{//数组名本身就是一个地址, &表示取地址 
        lena=strlen(str);//计算字符串长度的函数
    }
    for(i=0;i<lena;i++){
        a[i]=str[lena-1-i]-'0';//ASCII表 :'9'-'0'=9 
    } 
    /*输入第二个加数*/
    scanf("%s",str);
    lenb=strlen(str);
    for(int i=0;i<lenb;i++){
        b[i]=str[lenb-1-i]-'0';
    } 
    /*进行加法*/
    //求长度 
    len=(lena>lenb)?lena:lenb;//求出得数最接近的长度 
    /*算法核心*/ 
    for(i=0;i<len;i++){
        c[i]+=a[i]+b[i];//本位的结果 
        c[i+1]=c[i]/10;//判断是否需要进位 
        c[i]=c[i]%10;//留下进位后需要的部分 
    }
    if(c[i]){
        len++;
    }//最后一位是否需要进位;
    for(i=0;i<len;i++){ 
        printf("%d",c[len-1-i]);
    }//倒序输出
    return 0;
 } 

(2)高精度减法

题意:求A-B

#include<iostream>
using namespace std;
char a[10100],b[10100],ans[10100];
int slen(char*x){
   int l=0;
   while(x[l++]);
   return --l;
}
bool strcmp(char*x,char*y){
   int xl=slen(x),yl=slen(y);
   if(xl==yl){
       for(int i=0;i<xl;i++){
           if(x[i]>y[i])return 1;
           else if(x[i]<y[i])return 0;
       }
   }
   else return xl>yl;
}
bool check(int*ansi,int cnt){
   for(int i=0;i<cnt;i++){
       if(ansi[i])return 0;
   }
   return 1;
}
void jf(char*x,char*y,bool cmp){
   bool flag1=0,flag2=0;
   int tmp=0;
   int xl=slen(x),yl=slen(y);
   int ai[10100]={},bi[10100]={},ansi[10100]={};
   for(int i=0;i<xl;i++)ai[i]=x[xl-1-i]-'0';           
   for(int i=0;i<yl;i++)bi[i]=y[yl-1-i]-'0';
   for(int i=0;i<xl;i++){
       if(ai[i]<bi[i]){
           ansi[i]=ai[i]+10-bi[i];
           ai[i+1]--;
       }else ansi[i]=ai[i]-bi[i];
   }
   if(check(ansi,xl)){
       ans[0]='0';
       return;
   }
   if(cmp){
       for(int i=0;i<xl;i++){
           if(ansi[xl-1-i]==0&&!flag1)tmp++;
           if(ansi[xl-1-i])flag1=1;
           if(flag1)ans[i-tmp]=ansi[xl-1-i]+'0';
       }
   }else{
       ans[0]='-'
       for(int i=1;i<xl+1;i++){
           if(!ansi[xl-i]&&!flag1)tmp++;
           if(ansi[xl-i])flag1=1;
           if(flag1)ans[i-tmp]=ansi[xl-i]+'0';
       }
   }   
}
int main(){
   cin>>a>>b;
   if(strcmp(a,b)){
       jf(a,b,1);
   }else jf(b,a,0);
   for(int i=0;i<slen(a)+5;i++){
       cout<<ans[i];
   }
}

(3)高精度除法

题意:求A/B

#include<iostream>
#include<cstring>
#define max(x,y) (x>y)?x:y
#define min(x,y) (x>y)?y:x
using namespace std;
long long a,b,c,n;
long long s[10005],s2[10005];
string str;
int main(){
    cin>>str>>b;//cin>>c>>a;
    for(int i=1;i<=str.size();i++){
        s[i]=str[i-1]-'0';
    }
    for(int i=1;i<=str.size();i++){
        s2[i]=(c*10+s[i])/b;
        c=(c*10+s[i])%b;
    }
    n=1;
    for (int i=1;s2[n]==0&&str.size()>n;i++){
    	n++;
    }
    for(int i=n;i<=str.size();i++){
        cout<<s2[i];
    }
    return 0;
}

(4)高精度乘法

题意:求A*B

#include<iostream>
#include<cstring>
using namespace std;
char a1[20000],b1[20000];
int a[20000],b[20000],c[50000],i,j,len;
int main(){
    //输入两个因数 
    cin>>a1>>b1;
    a[0]=strlen(a1);
    b[0]=strlen(b1);
    for(i=1;i<=a[0];i++){
        a[i]=a1[a[0]-i]-'0';
    } 
    for(i=1;i<=b[0];i++){
        b[i]=b1[b[0]-i]-'0';
    } 
    /*算乘法,c数组中的每个数的值算出来*/ 
    for(i=1;i<=a[0];i++){
          for(j=1;j<=b[0];j++){
              c[i+j-1]+=a[i]*b[j];
          }
    }
    len=a[0]+b[0];
    /*进位*/ 
    for(i=1;i<len;i++){
        if(c[i]>9){
            c[i+1]+=c[i]/10;
            c[i]%=10;
          }
    } 
    while(c[len]==0&&len>1)len--;//去掉不满足位 
    /*输出*/ 
    for(i=len;i>=1;i--){
        cout<<c[i];
    }
    return 0;	
 } 

2.并查集 || 难度:普及-

题意:第一行包含两个整数 N , M N,M N,M ,表示共有 N N N 个元素和 M M M 个操作。

接下来 M M M 行,每行包含三个整数 Z i , X i , Y i Z_i,X_i,Y_i Zi,Xi,Yi

Z i = 1 Z_i=1 Zi=1 时,将 X i X_i Xi Y i Y_i Yi 所在的集合合并。

Z i = 2 Z_i=2 Zi=2 时,输出 X i X_i Xi Y i Y_i Yi 是否在同一集合内,是的输出 Y Y Y ;否则输出 N N N

分析:

并查集的单次查询理想复杂度应该是 O ( l o g   n ) O(log\ n) O(log n) 的,但是如果有一个这样的数据,并查集的复杂度就是 O ( n ) O(n) O(n)

为了避免这种情况,我们需对路径进行压缩。
即当我们经过找到祖先节点后,回溯的时候顺便将它的子孙节点都直接指向祖先,使以后的查找复杂度变回 O ( l o g   n ) O(log\ n) O(log n) 甚至更低。

#include<iostream>
using namespace std;
int n,m,x,y,z;
int fax,fay,fa[10005];
int found(int x){
	if(fa[x]==x) return x;
	return fa[x]=found(fa[x]);
}
int main(){
    cin>>n>>m;
    for (int i=1;i<=n;i++){
        fa[i]=i;
    }
    for (int i=1;i<=m;i++){
        cin>>z>>x>>y;
        fax=found(x);
        fay=found(y);
        if(z==1){
            if(fax!=fay){
                fa[fax]=fay;
            }
        }
        else{
            if(fax==fay) cout<<"Y\n";
            else cout<<"N\n";
        }
    }
    return 0;
}

3.快速幂 || 难度:普及-

题意:给你三个整数 a , b , p a,b,p a,b,p,求 a b   m o d   p a^b \bmod p abmodp
输出一行一个字符串 a^b mod p=s

好题解.

#include<iostream>
using namespace std;
long long a,b,p;
long long ans,tzy,tzy2;//替罪羊
int main(){
    cin>>a>>b>>p;
    ans=1%p;
    tzy=a;tzy2=b;
    while(b){
        if(b%2!=0){
            ans=(ans*a)%p;
        }
        a=(a*a)%p;
        b/=2;//b>>=2;
    }
    cout<<tzy<<"^"<<tzy2<<" mod "<<p<<"="<<ans<<"\n";
    return 0;
}

4.线性筛素数 || 难度:普及-

题意:第一行包含两个正整数 n , q n,q n,q,分别表示查询的范围和查询的个数。
接下来 q q q 行每行一个正整数 k k k,表示查询第 k k k 小的素数。
n = 1 0 8 n=10^8 n=108
1 ≤ q ≤ 1 0 6 1 \le q \le 10^6 1q106

好题解*2

#include<iostream>
#includehttps://www.luogu.com.cn/problem/P3383<cstdio>
using namespace std;
int n,q,k,a[100000005],b[100000005];
int t;
template <typename T> void read(T &x){
	x = 0;
	bool f = 0;
	char c = getchar();
	while (c < '0' || c > '9') f |= c == '-', c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	if (f) x = -x;
}
template <typename T> void write(T x){
	if (x < 0) putchar('-'), x = -x;
	if (x < 10) putchar(x + '0');
	else write(x / 10), putchar(x % 10 + '0');
}
int main(){
    read(n),read(q);
    a[0]=a[1]=1;
    for(int i=2;i<=n;i++){
        if(!a[i]){
        	++t;
        	b[t]=i;
		}
        for(int j=1;j<=t&&i*b[j]<=n;j++){
            a[b[j]*i]=1;
            if(i%b[j]==0){
            	break;
			}
		}
    }
    for(int i=1;i<=q;i++){
        read(k);
        write(b[k]);
        cout<<endl;
    }
    return 0;
}

5.快速排序 || 难度:普及-

题意:利用快速排序算法将读入的 N N N 个数从小到大排序后输出。

不错的题解

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
int n,a[1000001];
using namespace std;
void qsort(int l,int r){//应用二分思想
    int mid=a[(l+r)/2];//中间数
    int i=l,j=r;
    do{
        while(a[i]<mid) i++;//查找左半部分比中间数大的数
        while(a[j]>mid) j--;//查找右半部分比中间数小的数
        if(i<=j){//如果有一组不满足排序条件(左小右大)的数
            swap(a[i],a[j]);//交换
            i++;
            j--;
        }
    }
	while(i<=j);//这里注意要有=
    if(l<j) qsort(l,j);//递归搜索左半部分
    if(i<r) qsort(i,r);//递归搜索右半部分
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++) {
    	cin>>a[i];
    }
    qsort(1,n);
    for(int i=1;i<=n;i++) {
    	cout<<a[i]<<" ";
    }
    return 0;
}

6.堆 || 难度:普及-

题意:
第一行是一个整数,表示操作的次数 n n n
接下来 n n n 行,每行表示一次操作。每行首先有一个整数 o p op op 表示操作类型。

  • o p = 1 op = 1 op=1,则后面有一个整数 x x x,表示要将 x x x 加入数列。
  • o p = 2 op = 2 op=2,则表示要求输出数列中的最小数。
  • o p = 3 op = 3 op=3,则表示删除数列中的最小数。如果有多个数最小,只删除 1 1 1 个。

来一张图了解一下堆(这里是小根堆):

不难看出,对于堆的每个子树,它同样也是一个堆(因为是完全二叉树嘛)

1.插入:
来几张图感性理解亿下:

事实上堆的插入就是把新的元素放到堆底,然后检查它是否符合堆的性质,如果符合就丢在那里了,如果不符合,那就和它的父亲交换一下,一直交换交换交换,直到符合堆的性质,那么就插入完成了。
2.删除
再来几张图感性理解亿下?

我们要保证删除后这一整个堆还是个完好的小根堆

首先在它的两个儿子里面,找一个比较小的,和它交换一下,但是还是没法删除,因为下方还有节点,那就继续交换。

以上内容选自:这篇题解

(1)STL版

#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> > p;
int n,op,x;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>op;
        if(op==1){
            cin>>x;
            p.push(x);
        }
        else if(op==2){
            cout<<p.top()<<"\n";
        }
        else if(op==3) p.pop();
    }
    return 0;
}

(2)手写堆版

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1000005;
struct Myqueue{
    long long last=0,a[MAXN];
    Myqueue(){a[1]=0; for(int i=2;i<=1000000;i++) a[i]=1e12;}
    inline int top(){return a[1];}
    void push(int x){
        a[++last]=x;
        int tmp=last;
        while(a[tmp]<a[tmp>>1])
            swap(a[tmp],a[tmp>>1]),tmp>>=1;
    }
    void pop(){
        a[1]=1e12;
        swap(a[1],a[last]);
        int tmp=1;
        while(a[tmp]>min(a[(tmp<<1)],a[(tmp<<1)+1])){
            if(a[(tmp<<1)]<a[(tmp<<1)+1]) swap(a[tmp],a[tmp<<1]),tmp<<=1;
            else swap(a[tmp],a[(tmp<<1)+1]),tmp=(tmp<<1)+1;
        }
        last--;
    }
};
Myqueue q;
int main(){
    int T,op; scanf("%lld",&T);
    long long x;
    while(T--){
        scanf("%lld",&op);
        if(op==1) scanf("%lld",&x),q.push(x);
        if(op==2) printf("%lld\n",q.top());
        if(op==3) q.pop();
    }
    return 0;
}

(1)自然溢出哈希

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
ull base=131;
ull a[10010];
char s[10010];
int n,ans=1;
ull hashs(char s[]){
    int len=strlen(s);
    ull ans=0;
    for (int i=0;i<len;i++)
        ans=ans*base+(ull)s[i];
    return ans&0x7fffffff;
}
main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%s",s);
        a[i]=hashs(s);
    }
    sort(a+1,a+n+1);
    for (int i=2;i<=n;i++)
        if (a[i]!=a[i-1])
            ans++;
    printf("%d\n",ans);
}

字符串哈希 || 难度:普及-

题意或许放不了,直接上板子!

(2)单模数哈希

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
ull base=131;
ull a[10010];
char s[10010];
int n,ans=1;
ull mod=19260817;
ull hashs(char s[]){
    int len=strlen(s);
    ull ans=0;
    for (int i=0;i<len;i++)
        ans=(ans*base+(ull)s[i])%mod;
    return ans;
}
main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%s",s);
        a[i]=hashs(s);
    }
    sort(a+1,a+n+1);
    for (int i=2;i<=n;i++)
        if (a[i]!=a[i-1])
            ans++;
    printf("%d\n",ans);
}

(3)双模数哈希

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
ull base=131;
struct data{
    ull x,y;
}a[10010];
char s[10010];
int n,ans=1;
ull mod1=19260817;
ull mod2=19660813;
ull hash1(char s[]){
    int len=strlen(s);
    ull ans=0;
    for (int i=0;i<len;i++)
        ans=(ans*base+(ull)s[i])%mod1;
    return ans;
}
ull hash2(char s[]){
    int len=strlen(s);
    ull ans=0;
    for (int i=0;i<len;i++)
        ans=(ans*base+(ull)s[i])%mod2;
    return ans;
}
bool comp(data a,data b){
    return a.x<b.x;
}
main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%s",s);
        a[i].x=hash1(s);
        a[i].y=hash2(s);
    }
    sort(a+1,a+n+1,comp);
    for (int i=2;i<=n;i++)
        if (a[i].x!=a[i-1].x || a[i-1].y!=a[i].y)
            ans++;
    printf("%d\n",ans);
}

(4)只用一个 1 0 18 10^{18} 1018质数的哈希

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
ull base=131;
ull a[10010];
char s[10010];
int n,ans=1;
ull mod=212370440130137957ll;//是质数!!
ull hashs(char s[]){
    int len=strlen(s);
    ull ans=0;
    for (int i=0;i<len;i++)
        ans=(ans*base+(ull)s[i])%mod;
    return ans;
}
main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++){
        scanf("%s",s);
        a[i]=hashs(s);
    }
    sort(a+1,a+n+1);
    for (int i=2;i<=n;i++)
        if (a[i]!=a[i-1])
            ans++;
    printf("%d\n",ans);
}

8.最小生成树 || 难度:普及-

题意:
第一行包含两个整数 N , M N,M N,M,表示该图共有 N N N 个结点和 M M M 条无向边。接下来 M M M 行每行包含三个整数 X i , Y i , Z i X_i,Y_i,Z_i Xi,Yi,Zi,表示有一条长度为 Z i Z_i Zi 的无向边连接结点 X i , Y i X_i,Y_i Xi,Yi

如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz

(1)kruskal算法

#include<bits/stdc++.h>
const int maxn = 1e6 + 1;
inline int read(){
	register int x = 0, ch = getchar(), f = 1;
	while(!isdigit(ch)){if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
	return x * f;
}
int n, m;
struct node{
	int u,v,w;
}e[maxn];
int fa[maxn], cnt, sum, num;
void add(int x, int y, int w){
	e[++ cnt].u = x;
	e[cnt].v = y;
	e[cnt].w = w;
}
bool cmp(node x, node y){
	return x.w < y.w;
}
int find(int x){
	return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);//路径压缩
}
void kruskal(){
	for(int i = 1; i <= cnt; i ++){
		int x = find(e[i].u);
		int y = find(e[i].v);
		if(x == y) continue;
		fa[x] = y;
		sum += e[i].w;
		if(++ num == n - 1) break;//如果构成了一颗树 
	}
}
int main(){
    n = read();
    m = read();
    for(int i = 1; i <= n; i ++) fa[i] = i;
    while(m --){
        int x, y, w;
        x = read();
        y = read();
        w = read(); 
        add(x, y, w);
    }
    std:: sort(e + 1, e + 1 + cnt, cmp);
    kruskal();
    printf("%d",sum);
    return 0;
}

(2)prim算法

#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int book[100];//用于记录这个点有没有被访问过
int dis[100];//用于记录距离树的距离最短路程
int MAX = 99999;//边界值
int maps[100][100];//用于记录所有边的关系
int i,j,k;//循环变量
int n,m;//输入的N个点,和M条边
int x,y,z;//输入变量
int min,minIndex;
int sum=0;//记录最后的答案
int main(){
    cin>>n>>m;
    //初始化maps,除了自己到自己是0其他都是边界值
    for (i = 1; i <= n; i++){
        for (j = 1; j <= n; j++){
            if(i!=j) maps[i][j] = MAX;
            else maps[i][j] = 0;
        }
    }       
    for (i = 1; i <= m; i++){
        cin>>x>>y>>z;//输入的为无向图
        maps[x][y] = z;
        maps[y][x] = z;
    }
    //初始化距离数组,默认先把离1点最近的找出来放好
    for (i = 1; i <= n; i++)
        dis[i] = maps[1][i];
    book[1]=1;//记录1已经被访问过了
    for (i = 1; i <= n-1; i++){//1已经访问过了,所以循环n-1次
        min = MAX;//对于最小值赋值,其实这里也应该对minIndex进行赋值,但是我们承认这个图一定有最小生成树而且不存在两条相同的边
        //寻找离树最近的点
        for (j = 1; j <= n; j++){
            if(book[j] ==0 && dis[j] < min){
                min = dis[j];
                minIndex = j;
            }
        }
        //记录这个点已经被访问过了
        book[minIndex] = 1;
        sum += dis[minIndex];
        for (j = 1; j <= n; j++){
            //如果这点没有被访问过,而且这个点到任意一点的距离比现在到树的距离近那么更新
            if(book[j] == 0 && maps[minIndex][j] < dis[j])
                dis[j] = maps[minIndex][j];
        }
    }
    cout<<sum<<endl;
    return 0;
}

(3)链式前项星存图

#include<bits/stdc++.h>
using namespace std;
#define re register
#define il inline
il int read()
{
    re int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}//快读,不理解的同学用cin代替即可
#define inf 123456789
#define maxn 5005
#define maxm 200005
struct edge{
    int v,w,next;
}e[maxm<<1];
//注意是无向图,开两倍数组
int head[maxn],dis[maxn],cnt,n,m,tot,now=1,ans;
//已经加入最小生成树的的点到没有加入的点的最短距离,比如说1和2号节点已经加入了最小生成树,那么dis[3]就等于min(1->3,2->3)
bool vis[maxn];
//链式前向星加边
il void add(int u,int v,int w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt;
}
//读入数据
il void init(){
    n=read(),m=read();
    for(re int i=1,u,v,w;i<=m;++i){
        u=read(),v=read(),w=read();
        add(u,v,w),add(v,u,w);
    }
}
il int prim(){
    //先把dis数组附为极大值
    for(re int i=2;i<=n;++i){
        dis[i]=inf;
    }
    //这里要注意重边,所以要用到min
    for(re int i=head[1];i;i=e[i].next){
        dis[e[i].v]=min(dis[e[i].v],e[i].w);
    }
    while(++tot<n){//最小生成树边数等于点数-1
        re int minn=inf;//把minn置为极大值
        vis[now]=1;//标记点已经走过
        //枚举每一个没有使用的点
        //找出最小值作为新边
        //注意这里不是枚举now点的所有连边,而是1~n
        for(re int i=1;i<=n;++i){
            if(!vis[i]&&minn>dis[i]){
                minn=dis[i];
                now=i;
            }
        }
        ans+=minn;
        //枚举now的所有连边,更新dis数组
        for(re int i=head[now];i;i=e[i].next){
            re int v=e[i].v;
            if(dis[v]>e[i].w&&!vis[v]){
                dis[v]=e[i].w;
            }
        }
    }
    return ans;
}
int main(){
    init();
    printf("%d",prim());
    return 0;
}

(4)优先队列+堆优化

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define R register int
using namespace std;
int k,n,m,cnt,sum,ai,bi,ci,head[5005],dis[5005],vis[5005];
struct Edge{
    int v,w,next;
}e[400005];
void add(int u,int v,int w){
    e[++k].v=v;
    e[k].w=w;
    e[k].next=head[u];
    head[u]=k;
}
typedef pair <int,int> pii;
priority_queue <pii,vector<pii>,greater<pii> > q;
void prim(){
    dis[1]=0;
    q.push(make_pair(0,1));
    while(!q.empty()&&cnt<n){
        int d=q.top().first,u=q.top().second;
        q.pop();
        if(vis[u]) continue;
        cnt++;
        sum+=d;
        vis[u]=1;
        for(R i=head[u];i!=-1;i=e[i].next)
            if(e[i].w<dis[e[i].v])
                dis[e[i].v]=e[i].w,q.push(make_pair(dis[e[i].v],e[i].v));
    }
}
int main(){
    memset(dis,127,sizeof(dis));
    memset(head,-1,sizeof(head));
    scanf("%d%d",&n,&m);
    for(R i=1;i<=m;i++){
        scanf("%d%d%d",&ai,&bi,&ci);
        add(ai,bi,ci);
        add(bi,ai,ci);
    }
    prim();
    if (cnt==n)printf("%d",sum);
    else printf("orz");
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值