LCT例题

P3690 【模板】Link Cut Tree (动态树)

#include<cstdio>
#include<iostream>
using namespace std;
const int N=320000; 
int w[N],n,m,opt,x,y;
struct LCT{
    int ch[N][2],f[N],val[N],flag[N],tot,tmp[N];
    int get(int x){
        return ch[f[x]][1]==x;
    }
    void pushdown(int x){int l=ch[x][0],r=ch[x][1];
        if(flag[x]){
            flag[l]^=1;flag[r]^=1;flag[x]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    }
    void update(int x){
        val[x]=val[ch[x][0]]^val[ch[x][1]]^w[x];
    }
    bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
    void retoto(int x){
        int old=f[x],old2=f[old],opt=get(x),opt2=get(old);
        if(!isroot(old)) ch[old2][opt2]=x;f[x]=old2;
        f[old]=x;f[ch[x][opt^1]]=old;
        ch[old][opt]=ch[x][opt^1];ch[x][opt^1]=old;
        update(old);update(x);
    }
    void splay(int x){tot=1;tmp[1]=x;
        for(int now=x;!isroot(now);now=f[now]) tmp[++tot]=f[now];
        for(;tot;tot--) pushdown(tmp[tot]);
        for(int fa;(fa=f[x])&&(!isroot(x));retoto(x))
        if(!isroot(fa))retoto(get(x)==get(fa)?fa:x);
    }//认父不认子 
    void access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y,update(x);}
    void makeroot(int x){access(x);splay(x);flag[x]^=1;} 
    int oldroot(int x){access(x),splay(x);while(ch[x][0]) x=ch[x][0];return x;} 
    void split(int x,int y){makeroot(x);access(y);splay(y);}
    void cut(int y,int x){split(x,y);if(x==ch[y][0]) ch[y][0]=0,f[x]=0;}
    void link(int x,int y){makeroot(x);f[x]=y;}
    int query(int x,int y){split(x,y);return val[y];}
}T;

int main(){scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&w[i]),T.val[i]=w[i];
    while(m--){scanf("%d%d%d",&opt,&x,&y);
        if(!opt) printf("%d\n",T.query(x,y));
        else if(opt==1) {if(T.oldroot(x)!=T.oldroot(y)) T.link(x,y);}
        else if(opt==2) {if(T.oldroot(x)==T.oldroot(y)) T.cut(x,y);}
        else T.access(x),T.splay(x),w[x]=y,T.update(x);
    }
}
P2147 [SDOI2008]Cave 洞穴勘测
#include<cstdio>
#include<iostream>
using namespace std;
const int N=20000; 
int w[N],n,m,opt,x,y;char s[20];
struct LCT{
    int ch[N][2],f[N],flag[N],tot,tmp[N];
    int get(int x){
        return ch[f[x]][1]==x;
    }
    void pushdown(int x){int l=ch[x][0],r=ch[x][1];
        if(flag[x]){
            flag[l]^=1;flag[r]^=1;flag[x]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    }
    bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
    void retoto(int x){
        int old=f[x],old2=f[old],opt=get(x),opt2=get(old);
        if(!isroot(old)) ch[old2][opt2]=x;f[x]=old2;
        f[old]=x;f[ch[x][opt^1]]=old;
        ch[old][opt]=ch[x][opt^1];ch[x][opt^1]=old;
    }
    void splay(int x){tot=1;tmp[1]=x;
        for(int now=x;!isroot(now);now=f[now]) tmp[++tot]=f[now];
        for(;tot;tot--) pushdown(tmp[tot]);
        for(int fa;(fa=f[x])&&(!isroot(x));retoto(x))
        if(!isroot(fa))retoto(get(x)==get(fa)?fa:x);
    }//认父不认子 
    void access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y;}
    void makeroot(int x){access(x);splay(x);flag[x]^=1;} 
    int oldroot(int x){access(x),splay(x);while(ch[x][0]) x=ch[x][0];return x;} 
    void split(int x,int y){makeroot(x);access(y);splay(y);}
    void cut(int y,int x){split(x,y);if(x==ch[y][0]) ch[y][0]=0,f[x]=0;}
    void link(int x,int y){makeroot(x);f[x]=y;}
}T;

int main(){scanf("%d%d",&n,&m);

    while(m--){cin>>s;
        scanf("%d%d",&x,&y);
        if(s[0]=='Q') {if(T.oldroot(x)==T.oldroot(y))printf("Yes\n");else printf("No\n");}
        else if(s[0]=='C') {if(T.oldroot(x)!=T.oldroot(y)) T.link(x,y);}
        else if(s[0]=='D') {if(T.oldroot(x)==T.oldroot(y)) T.cut(x,y);}
    }
}

P3703 [SDOI2017]树点涂色
这个题转化一下,一操作就是把他们弄到一棵树里,因为,多了一个颜色吗,这样虚子树的权值要+1,子树要减一
而每次都加修改1,差最大值,就是权值,所以树剖线段树维护

#include<cstdio>
#include<iostream>
using namespace std;
const int M=110000; 
int n,m,to[2*M],nex[M*2],head[M],tot,f[M],dep[M],top[M],cnt,size[M],son[M],id[M],low[M];
void add(int x,int y){
    nex[++tot]=head[x];
    to[tot]=y;head[x]=tot;
}
struct xianduantree{
    int maxn[4*M],ad[4*M];
    void update(int x){
        maxn[x]=max(maxn[x<<1],maxn[x<<1|1]);
    }
    void built(int o,int l,int r){
    if(l==r) maxn[o]=0,ad[o]=0;
    else {
        int mid=(l+r)>>1;
        built(o<<1,l,mid);
        built(o<<1|1,mid+1,r);
        update(o);  
        }
    }
    void pushdown(int o){
        ad[o<<1]=(ad[o<<1]+ad[o]);
        ad[o<<1|1]=(ad[o<<1|1]+ad[o]);
        maxn[o<<1]=maxn[o<<1]+ad[o];
        maxn[o<<1|1]=maxn[o<<1|1]+ad[o];
        ad[o]=0;
    }
    void add(int o,int l,int r,int ql,int qr,int ins){
        if(l>qr||r<ql) return ;
        if(l>=ql&&r<=qr) {
            ad[o]=(ad[o]+ins);
            maxn[o]=maxn[o]+ins;
            return ;
        }
        int mid=(l+r)>>1;
        pushdown(o);
        add(o<<1,l,mid,ql,qr,ins);
        add(o<<1|1,mid+1,r,ql,qr,ins);
        update(o);
    }
    int ask(int o,int l,int r,int ql,int qr){
        if(l>qr||r<ql) return 0;
        if(l>=ql&&r<=qr) return maxn[o];
        int mid=(l+r)>>1;
        pushdown(o);
        return max(ask(o<<1,l,mid,ql,qr),ask(o<<1|1,mid+1,r,ql,qr));
    }
}tr;
struct LCT{
    int ch[M][2],f[M];
    int get(int x){
        return ch[f[x]][1]==x;
    }

    bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
    void retoto(int x){
        int old=f[x],old2=f[old],opt=get(x),opt2=get(old);
        if(!isroot(old)) ch[old2][opt2]=x;f[x]=old2;
        f[old]=x;f[ch[x][opt^1]]=old;
        ch[old][opt]=ch[x][opt^1];ch[x][opt^1]=old;
    }
    void splay(int x){
        for(int fa;(fa=f[x])&&(!isroot(x));retoto(x))
        if(!isroot(fa))retoto(get(x)==get(fa)?fa:x);
    }//认父不认子 
    void access(int x){for(int y=0;x;y=x,x=f[x]) {
        splay(x);int t=ch[x][1];
        while(ch[t][0]) t=ch[t][0];
        tr.add(1,1,cnt,id[t],low[t],1);t=y;
        while(ch[t][0]) t=ch[t][0];
        tr.add(1,1,cnt,id[t],low[t],-1);
        ch[x][1]=y;
    }}
}T;
int dfs1(int x){
    size[x]=1;dep[x]=dep[f[x]]+1;
    int maxsi=0;
    for(int i=head[x];i;i=nex[i]){
        int tmp=to[i];
        if(tmp!=f[x]){
            f[tmp]=x;
            int siz=dfs1(tmp);
            size[x]+=siz;
            if(maxsi<siz)
            son[x]=tmp,maxsi=siz;
        }
    }
    return size[x];
}
void dfs2(int x,int topx){
    top[x]=topx;
    id[x]=++cnt;
    if(!son[x]){low[x]=cnt;return ;}
    dfs2(son[x],topx);
    for(int i=head[x],tmp;i;i=nex[i])
    if(!id[tmp=to[i]])
    dfs2(tmp,tmp);
    low[x]=cnt;
}
int lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        x=f[top[x]];
    } 
    return dep[x]>dep[y]?y:x;
}
int main(){scanf("%d%d",&n,&m);
    for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
    dfs1(1);dfs2(1,1);
    tr.built(1,1,cnt);
    for(int i=1;i<=n;i++) T.f[i]=f[i],tr.add(1,1,cnt,id[i],low[i],1);
    while(m--){int x,y,opt;
        scanf("%d%d",&opt,&x);
        if(opt==1) T.access(x);
        else if(opt==2) scanf("%d",&y),opt=lca(x,y),printf("%d\n",tr.ask(1,1,cnt,id[x],id[x])
        +tr.ask(1,1,cnt,id[y],id[y])-2*tr.ask(1,1,cnt,id[opt],id[opt])+1);
        else  printf("%d\n",tr.ask(1,1,cnt,id[x],low[x]));
    }

}

P3203 [HNOI2010]弹飞绵羊

#include<cstdio>
#include<iostream>
using namespace std;
const int N=420000; 
int w[N],n,m,opt,x,y;
struct LCT{
    int ch[N][2],f[N],val[N],flag[N],tot,tmp[N];
    int get(int x){
        return ch[f[x]][1]==x;
    }
    void pushdown(int x){int l=ch[x][0],r=ch[x][1];
        if(flag[x]){
            flag[l]^=1;flag[r]^=1;flag[x]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    }
    void update(int x){
        val[x]=val[ch[x][0]]+val[ch[x][1]]+1;
    }
    bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
    void retoto(int x){
        int old=f[x],old2=f[old],opt=get(x),opt2=get(old);
        if(!isroot(old)) ch[old2][opt2]=x;f[x]=old2;
        f[old]=x;f[ch[x][opt^1]]=old;
        ch[old][opt]=ch[x][opt^1];ch[x][opt^1]=old;
        update(old);update(x);
    }
    void splay(int x){tot=1;tmp[1]=x;
        for(int now=x;!isroot(now);now=f[now]) tmp[++tot]=f[now];
        for(;tot;tot--) pushdown(tmp[tot]);
        for(int fa;(fa=f[x])&&(!isroot(x));retoto(x))
        if(!isroot(fa))retoto(get(x)==get(fa)?fa:x);
    }//认父不认子 
    void access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y,update(x);}
    void makeroot(int x){access(x);splay(x);flag[x]^=1;} 
    int oldroot(int x){access(x),splay(x);while(ch[x][0]) x=ch[x][0];return x;} 
    void split(int x,int y){makeroot(x);access(y);splay(y);}
    void cut(int y,int x){split(x,y);if(x==ch[y][0]) ch[y][0]=0,f[x]=0;}
    void link(int x,int y){makeroot(x);f[x]=y;}
    int query(int x){makeroot(n+1);access(x);splay(x);return val[ch[x][0]];}
}T;

int main(){scanf("%d",&n);
    for(int i=1;i<=n+1;i++) T.val[i]=1;
    for(int i=1;i<=n;i++) {
        scanf("%d",&w[i]);
         T.f[i]=(i+w[i]<=n)?i+w[i]:(n+1);
    }
    scanf("%d",&m);
    while(m--){scanf("%d%d",&opt,&x);x++;
        if(opt==1) printf("%d\n",T.query(x));
        else if(opt==2) {
            scanf("%d",&y);T.cut(x,(w[x]+x<=n)?x+w[x]:(n+1));T.link(x,(y+x<=n)?x+y:(n+1));w[x]=y;
        }
    }
}
P2387 [NOI2014]魔法森林

这个题是一个二维问题,没有修改,直接用扫描线,降维
然后LCA维护最小生成树和最大边;

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=320000,INF=510000; 
int w[N],n,m,opt,x,y,s[N],t[N],id,ans=INF;
struct node{
    int u,v,a,b;
}e[N];
struct LCT{
    int ch[N][2],f[N],val[N],flag[N],tot,tmp[N],maxs[N];
    int get(int x){
        return ch[f[x]][1]==x;
    }
    void pushdown(int x){int l=ch[x][0],r=ch[x][1];
        if(flag[x]){
            flag[l]^=1;flag[r]^=1;flag[x]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    }
    void update(int x){
        maxs[x]=x;
       if(val[maxs[ch[x][0]]]>val[maxs[x]]) maxs[x]=maxs[ch[x][0]];
       if(val[maxs[ch[x][1]]]>val[maxs[x]]) maxs[x]=maxs[ch[x][1]];
    }
    bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
    void retoto(int x){
        int old=f[x],old2=f[old],opt=get(x),opt2=get(old);
        if(!isroot(old)) ch[old2][opt2]=x;f[x]=old2;
        f[old]=x;f[ch[x][opt^1]]=old;
        ch[old][opt]=ch[x][opt^1];ch[x][opt^1]=old;
        update(old);update(x);
    }
    void splay(int x){tot=1;tmp[1]=x;
        for(int now=x;!isroot(now);now=f[now]) tmp[++tot]=f[now];
        for(;tot;tot--) pushdown(tmp[tot]);
        for(int fa;(fa=f[x])&&(!isroot(x));retoto(x))
        if(!isroot(fa))retoto(get(x)==get(fa)?fa:x);
    }//认父不认子 
    void access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y,update(x);}
    void makeroot(int x){access(x);splay(x);flag[x]^=1;} 
    int oldroot(int x){access(x),splay(x);while(ch[x][0]) x=ch[x][0];return x;} 
    void split(int x,int y){makeroot(x);access(y);splay(y);}
    void cut(int y,int x){split(x,y);if(x==ch[y][0]) ch[y][0]=0,f[x]=0;}
    void link(int x,int y){makeroot(x);f[x]=y;}
    void add(int x,int y,int z){
        if(oldroot(x)^oldroot(y)){id++;
            s[id]=x,t[id]=y;
            val[id]=z,maxs[id]=id;
            link(x,id),link(y,id);
        }
        else{
            split(x,y);
            int v=maxs[y];
            if(val[v]<z) return;
            cut(s[v],v),cut(t[v],v);id++;
            s[id]=x,t[id]=y;
            val[id]=z,maxs[id]=id;
            link(x,id),link(y,id);
        }
    }
    int query(int x,int y){if(oldroot(x)^oldroot(y)) return INF;split(x,y);
    return val[maxs[y]];}
}T;
bool cmp(node x,node y){
    return x.a!=y.a?x.a<y.a:x.b<y.b;
}
int main(){scanf("%d%d",&n,&m);id=n;
    for(int i=1;i<=m;i++)
     scanf("%d%d%d%d",&e[i].u,&e[i].v,&e[i].a,&e[i].b);
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=m;i++){
        T.add(e[i].u,e[i].v,e[i].b);
         ans=min(ans,e[i].a+T.query(1,n));
    }
    printf("%d\n",ans==INF?-1:ans);
}


P4172 [WC2006]水管局长
这个题离线做,把删边弄成加边
LCT维护最小生成树和最大边

#include<algorithm>
#include<iostream>
#define N 1500000
#include<cstdio>
using namespace std;
struct LCT{
    int ch[N][2],f[N],val[N],flag[N],tot,tmp[N],maxs[N];
    int get(int x){
        return ch[f[x]][1]==x;
    }
    void pushdown(int x){int l=ch[x][0],r=ch[x][1];
        if(flag[x]){
            flag[l]^=1;flag[r]^=1;flag[x]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    }
    void update(int x){
        maxs[x]=x;
       if(val[maxs[ch[x][0]]]>val[maxs[x]]) maxs[x]=maxs[ch[x][0]];
       if(val[maxs[ch[x][1]]]>val[maxs[x]]) maxs[x]=maxs[ch[x][1]];
    }
    bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
    void retoto(int x){
        int old=f[x],old2=f[old],opt=get(x),opt2=get(old);
        if(!isroot(old)) ch[old2][opt2]=x;f[x]=old2;
        f[old]=x;f[ch[x][opt^1]]=old;
        ch[old][opt]=ch[x][opt^1];ch[x][opt^1]=old;
        update(old);update(x);
    }
    void splay(int x){tot=1;tmp[1]=x;
        for(int now=x;!isroot(now);now=f[now]) tmp[++tot]=f[now];
        for(;tot;tot--) pushdown(tmp[tot]);
        for(int fa;(fa=f[x])&&(!isroot(x));retoto(x))
        if(!isroot(fa))retoto(get(x)==get(fa)?fa:x);
    }//认父不认子 
    void access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),ch[x][1]=y,update(x);}
    void makeroot(int x){access(x);splay(x);flag[x]^=1;} 
    int oldroot(int x){access(x),splay(x);while(ch[x][0]) x=ch[x][0];return x;} 
    void split(int x,int y){makeroot(x);access(y);splay(y);}
    void cut(int y,int x){split(x,y);if(x==ch[y][0]) ch[y][0]=0,f[x]=0;}
    void link(int x,int y){makeroot(x);f[x]=y;}
    int query(int x,int y){split(x,y);return maxs[y];}
}T;
struct eage{
    int u,v,l,id;
    bool f;
}e[N],q[N];
int n,m,Q;int f[N],ans[N];
bool comp1(eage aa,eage bb){
    return aa.u==bb.u?aa.v<bb.v:aa.u<bb.u;
}
bool comp2(eage aa,eage bb){
    return aa.l<bb.l;
}
bool comp3(eage aa,eage bb){
    return aa.id<bb.id;
}
int findit(int u,int v){
    int l=1,r=m;
    while(l<=r){
        int mid=(l+r)>>1;
        if(e[mid].u<u||(e[mid].u==u&&e[mid].v<v))l=mid+1;
        else if(e[mid].u==u&&e[mid].v==v)return mid;
        else r=mid-1;
    }
}

int get_f(int x){
    return x==f[x]?f[x]:f[x]=get_f(f[x]);
}
void KUSCER(){
    for(int i=1;i<=n;++i) f[i]=i;
    sort(e+1,e+m+1,comp3);int tot=0;
    for(int i=1;i<=m;++i){
        if(e[i].f) continue; 
        int x=get_f(e[i].u),y=get_f(e[i].v);
        if(x==y) continue;tot++;
        f[x]=y;
        T.link(e[i].u,i+n);
        T.link(e[i].v,i+n);
        if(tot==n-1) return;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&Q);
    for(int i=1;i<=m;++i){
        scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].l);
        if(e[i].u>e[i].v) swap(e[i].u,e[i].v);
    }

    sort(e+1,e+m+1,comp2);
    for(int i=1;i<=m;++i){
        e[i].id=i;
        T.val[n+i]=e[i].l;
        T.maxs[n+i]=n+i;
    }

    sort(e+1,e+m+1,comp1);
    for(int i=1,www;i<=Q;++i){
        scanf("%d%d%d",&www,&q[i].u,&q[i].v);www--;q[i].f=www;
        if(q[i].f==1){
            if(q[i].u>q[i].v) swap(q[i].u,q[i].v);
            int id=findit(q[i].u,q[i].v);
            q[i].id=e[id].id;e[id].f=1;
        }
    }
    KUSCER();
    for(int i=Q;i;--i) {
        if(q[i].f==0) ans[i]=T.val[T.query(q[i].u,q[i].v)];
        else{
            int bi=T.query(q[i].u,q[i].v);
            if(T.val[bi]>T.val[q[i].id+n]){
                T.cut(e[bi-n].u,bi);T.cut(e[bi-n].v,bi);
                T.link(q[i].u,q[i].id+n);T.link(q[i].v,q[i].id+n);
            }
        }
    }
    for(int i=1;i<=Q;++i) if(q[i].f==0) printf("%d\n",ans[i]);
    return 0;
}

P4219 [BJOI2014]大融合
我们发现这个题其实就是求虚子树个数的乘积
直接lct维护子树信息

#include<algorithm>
#include<iostream>
#define N 1500000
#include<cstdio>
using namespace std;
struct LCT{
    int ch[N][2],f[N],size[N],flag[N],tot,tmp[N],sise[N];
    int get(int x){
        return ch[f[x]][1]==x;
    }
    void pushdown(int x){int l=ch[x][0],r=ch[x][1];
        if(flag[x]){
            flag[l]^=1;flag[r]^=1;flag[x]^=1;
            swap(ch[x][0],ch[x][1]);
        }
    }
    void update(int x){
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1+sise[x];
    }
    bool isroot(int x){return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;}
    void retoto(int x){
        int old=f[x],old2=f[old],opt=get(x),opt2=get(old);
        if(!isroot(old)) ch[old2][opt2]=x;f[x]=old2;
        f[old]=x;f[ch[x][opt^1]]=old;
        ch[old][opt]=ch[x][opt^1];ch[x][opt^1]=old;
        update(old);update(x);
    }
    void splay(int x){tot=1;tmp[1]=x;
        for(int now=x;!isroot(now);now=f[now]) tmp[++tot]=f[now];
        for(;tot;tot--) pushdown(tmp[tot]);
        for(int fa;(fa=f[x])&&(!isroot(x));retoto(x))
        if(!isroot(fa))retoto(get(x)==get(fa)?fa:x);
    }//认父不认子 
    void access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),sise[x]+=size[ch[x][1]],sise[x]-=size[ch[x][1]=y],update(x);}
    void makeroot(int x){access(x);splay(x);flag[x]^=1;} 
    int oldroot(int x){access(x),splay(x);while(ch[x][0]) x=ch[x][0];return x;} 
    void split(int x,int y){makeroot(x);access(y);splay(y);}
    void cut(int y,int x){split(x,y);if(x==ch[y][0]) ch[y][0]=0,f[x]=0;}
    void link(int x,int y){split(x,y);f[x]=y;sise[y]+=size[x];update(y);}
}T;
int n,Q;

int main()
{
    scanf("%d%d%d",&n,&Q);
    for(int i=1;i<=n;i++) T.size[i]=1;
    while(Q--){char s[10];int x,y;
        scanf("%s%d%d",s,&x,&y);
        if(s[0]=='A') T.link(x,y);
        else {T.split(x,y);
            printf("%lld\n",1ll*(T.sise[x]+1)*(T.sise[y]+1));
        }
    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值