树链剖分小结板子

题目链接:树的统计Count

树链剖分(权值在点上)[单点修改 询问区间和/最大值]:
int a[30005];

struct node
{
    int tl,tr,maxx,sum;
    node():maxx(0),sum(0) {}
} tree[120020];

void pushup(int id)
{
    tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
    tree[id].maxx=max(tree[id<<1].maxx,tree[id<<1|1].maxx);
}

void build(int id,int tl,int tr)
{
    tree[id].tl=tl,tree[id].tr=tr;
    if(tl==tr)
    {
        tree[id].maxx=a[tl];
        tree[id].sum=a[tl];
    }
    else
    {
        int tm=(tl+tr)>>1;
        build(id<<1,tl,tm);
        build(id<<1|1,tm+1,tr);
        pushup(id);
    }
}

void update(int id,int wz,int val)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(tl==wz && wz==tr)
    {
        tree[id].maxx=val;
        tree[id].sum=val;
    }
    else
    {
        int tm=(tl+tr)>>1;
        if(tm>=wz)update(id<<1,wz,val);
        else update(id<<1|1,wz,val);
        pushup(id);
    }
}

int get_max(int id,int ql,int qr)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql<=tl && tr<=qr)return tree[id].maxx;
    int tm=(tl+tr)>>1,res1=-inf,res2=-inf;
    if(tm>=ql)res1=get_max(id<<1,ql,qr);
    if(tm<qr)res2=get_max(id<<1|1,ql,qr);
    return max(res1,res2);
}

int get_sum(int id,int ql,int qr)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql<=tl && tr<=qr)return tree[id].sum;
    int tm=(tl+tr)>>1;
    int sum=0;
    if(tm>=ql)sum+=get_sum(id<<1,ql,qr);
    if(tm<qr)sum+=get_sum(id<<1|1,ql,qr);
    return sum;
}

int pre[30005],siz[30005],dep[30005];
int top[30005],node_id[30005],heavy[30005];
int val[30005],idx=1;
vector<int>G[30005];

int dfs(int x,int fa,int depth)
{
    dep[x]=depth,pre[x]=fa;
    int res=1,maxx=0;
    int len=G[x].size();
    for(int i=0; i<len; i++)
    {
        if(G[x][i]==fa)continue;
        int t=dfs(G[x][i],x,depth+1);
        if(t>maxx)maxx=t,heavy[x]=G[x][i];
        res+=t;
    }
    return siz[x]=res;
}

void slpf(int x,int fa,int tp)
{
    node_id[x]=idx++;
    top[x]=tp;
    int len=G[x].size();
    if(heavy[x])slpf(heavy[x],x,tp);
    for(int i=0; i<len; i++)
    {
        int nex=G[x][i];
        if(nex==fa)continue;
        if(nex!=heavy[x])slpf(nex,x,nex);
    }
}

int getmax(int x,int y)
{
    int ans=-inf,res;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]>dep[top[y]])
        {
            res=get_max(1,node_id[top[x]],node_id[x]);
            x=pre[top[x]];
        }
        else
        {
            res=get_max(1,node_id[top[y]],node_id[y]);
            y=pre[top[y]];
        }
        if(res>ans)ans=res;
    }
    if(dep[x]>dep[y])swap(x,y);
    res=get_max(1,node_id[x],node_id[y]);
    if(res>ans)ans=res;
    return ans;
}

int getsum(int x,int y)
{
    int ans=0,res;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]>dep[top[y]])
        {
            res=get_sum(1,node_id[top[x]],node_id[x]);
            x=pre[top[x]];
        }
        else
        {
            res=get_sum(1,node_id[top[y]],node_id[y]);
            y=pre[top[y]];
        }
        ans+=res;
    }
    if(dep[x]>dep[y])swap(x,y);
    res=get_sum(1,node_id[x],node_id[y]);
    ans+=res;
    return ans;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n-1; i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1,0,1);
    slpf(1,0,1);
    for(int i=1; i<=n; i++)
        scanf("%d",&a[node_id[i]]);
    build(1,1,n);
    int q;
    scanf("%d",&q);
    while(q--)
    {
        char op[10];
        int x,y;
        scanf("%s%d%d",op,&x,&y);
        if(op[0]=='Q' && op[1]=='M')
            printf("%d\n",getmax(x,y));
        if(op[0]=='Q' && op[1]=='S')
            printf("%d\n",getsum(x,y));
        if(op[0]=='C')update(1,node_id[x],y);
    }
    return 0;
}

题目链接:树上操作

树链剖分(权值在点上)[单点/区间修改 询问区间和]:
struct node
{
    int tl,tr;
    ll lazy,sum;
    node():lazy(0),sum(0) {}
}tree[400020];

int a[100005];

void pushup(int id)
{
    tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
}

void build(int id,int tl,int tr)
{
    tree[id].tl=tl,tree[id].tr=tr;
    tree[id].lazy=tree[id].sum=0;
    if(tl==tr)tree[id].sum=(ll)a[tl];
    else
    {
        int tm=(tr+tl)>>1;
        build(id<<1,tl,tm);
        build(id<<1|1,tm+1,tr);
        pushup(id);
    }
}

void pushdown(int id)
{
    if(!tree[id].lazy)return;
    tree[id<<1].lazy+=tree[id].lazy;
    tree[id<<1|1].lazy+=tree[id].lazy;
    tree[id<<1].sum+=(tree[id<<1].tr-tree[id<<1].tl+1)*tree[id].lazy;
    tree[id<<1|1].sum+=(tree[id<<1|1].tr-tree[id<<1|1].tl+1)*tree[id].lazy;
    tree[id].lazy=0;
}

void update(int id,int ql,int qr,ll val)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql>tr || qr<tl)return;
    if(ql<=tl && tr<=qr)
    {
        tree[id].lazy+=val;
        tree[id].sum+=(tr-tl+1)*val;
        return;
    }
    pushdown(id);
    update(id<<1,ql,qr,val);
    update(id<<1|1,ql,qr,val);
    pushup(id);
}

ll get_sum(int id,int ql,int qr)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql>tr || qr<tl)return 0;
    if(ql<=tl && tr<=qr)return tree[id].sum;
    ll ans=0;
    pushdown(id);
    ans+=get_sum(id<<1,ql,qr);
    ans+=get_sum(id<<1|1,ql,qr);
    pushup(id);
    return ans;
}

int pre[100005],siz[100005],dep[100005];
int top[100005],node_id[100005],heavy[100005];
int val[100005],lson[100005],rson[100005],idx=0;
vector<int>G[100005];

int dfs(int x,int fa,int depth)
{
    dep[x]=depth,pre[x]=fa;
    int res=1,maxx=0;
    int len=G[x].size();
    for(int i=0; i<len; i++)
    {
        if(G[x][i]==fa)continue;
        int t=dfs(G[x][i],x,depth+1);
        if(t>maxx)maxx=t,heavy[x]=G[x][i];
        res+=t;
    }
    return siz[x]=res;
}

void slpf(int x,int fa,int tp)
{
    lson[x]=node_id[x]=++idx;
    top[x]=tp;
    int len=G[x].size();
    if(heavy[x])slpf(heavy[x],x,tp);
    for(int i=0; i<len; i++)
    {
        int nex=G[x][i];
        if(nex==fa)continue;
        if(nex!=heavy[x])slpf(nex,x,nex);
    }
    rson[x]=idx;
}

ll getsum(int x,int y)
{
    ll ans=0,res;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]>dep[top[y]])
        {
            res=get_sum(1,node_id[top[x]],node_id[x]);
            x=pre[top[x]];
        }
        else
        {
            res=get_sum(1,node_id[top[y]],node_id[y]);
            y=pre[top[y]];
        }
        ans+=res;
    }
    if(dep[x]>dep[y])swap(x,y);
    res=get_sum(1,node_id[x],node_id[y]);
    ans+=res;
    return ans;
}


int main()
{
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
    for(int i=1;i<=n-1;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(1,0,1);
    slpf(1,0,1);
    for(int i=1;i<=n;i++)
        a[node_id[i]]=val[i];
    build(1,1,n);
    while(q--)
    {
        int op,x;ll y;
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%lld",&x,&y);
            update(1,node_id[x],node_id[x],y);
        }
        if(op==2)
        {
            scanf("%d%lld",&x,&y);
            update(1,lson[x],rson[x],y);
        }
        if(op==3)
        {
            scanf("%d",&x);
            printf("%lld\n",getsum(1,x));
        }
    }
    return 0;
}

题目链接:Query on a tree

树链剖分(权值在边上)[单点修改 询问区间最大值]:
int a[10005];

struct node
{
    int tl,tr,val;
} tree[40020];

void pushup(int id)
{
    tree[id].val=max(tree[id<<1].val,tree[id<<1|1].val);
}

void build(int id,int tl,int tr)
{
    tree[id].tl=tl,tree[id].tr=tr;
    if(tl==tr)tree[id].val=a[tl];
    else
    {
        int tm=(tl+tr)>>1;
        build(id<<1,tl,tm);
        build(id<<1|1,tm+1,tr);
        pushup(id);
    }
}

void update(int id,int wz,int val)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(tl==wz && wz==tr)tree[id].val=val;
    else
    {
        int tm=(tl+tr)>>1;
        if(tm>=wz)update(id<<1,wz,val);
        else update(id<<1|1,wz,val);
        pushup(id);
    }
}

int getval(int id,int ql,int qr)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql<=tl && tr<=qr)return tree[id].val;
    int tm=(tl+tr)>>1,res1=0,res2=0;
    if(tm>=ql)res1=getval(id<<1,ql,qr);
    if(tm<qr)res2=getval(id<<1|1,ql,qr);
    return max(res1,res2);
}

struct edge
{
    int nex,id,val;
    edge(int nex,int id,int val):
        nex(nex),id(id),val(val) {}
};

int pre[10005],siz[10005],dep[10005];
int top[10005],edge_id[10005],heavy[10005];
int val[10005],ith[10005];
int idx=1;
vector<edge>G[10005];

void init(void)
{
    idx=1;
    memset(a,0,sizeof(a));
    memset(ith,0,sizeof(ith));
    memset(val,0,sizeof(val));
    memset(top,0,sizeof(top));
    memset(pre,0,sizeof(pre));
    memset(siz,0,sizeof(siz));
    memset(dep,0,sizeof(dep));
    memset(heavy,0,sizeof(heavy));
    memset(tree,0,sizeof(tree));
    memset(edge_id,0,sizeof(edge_id));
}

int dfs(int x,int fa,int depth)
{
    dep[x]=depth,pre[x]=fa;
    int res=1,maxx=0;
    int len=G[x].size();
    for(int i=0; i<len; i++)
    {
        int nex=G[x][i].nex;
        if(nex==fa)continue;
        int t=dfs(nex,x,depth+1);
        ith[G[x][i].id]=nex;
        val[nex]=G[x][i].val;
        if(t>maxx)
            maxx=t,heavy[x]=nex;
        res+=t;
    }
    return siz[x]=res;
}

void slpf(int x,int fa,int tp)
{
    int len=G[x].size();
    if(pre[x])edge_id[x]=idx++;
    top[x]=tp;
    if(heavy[x])slpf(heavy[x],x,tp);
    for(int i=0; i<len; i++)
    {
        int nex=G[x][i].nex;
        if(nex==fa)continue;
        if(nex!=heavy[x])
            slpf(nex,x,nex);
    }
}

int getmax(int x,int y)
{
    int ans=0,res;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]>dep[top[y]])
        {
            res=getval(1,edge_id[top[x]],edge_id[x]);
            x=pre[top[x]];
        }
        else
        {
            res=getval(1,edge_id[top[y]],edge_id[y]);
            y=pre[top[y]];
        }
        if(res>ans)ans=res;
    }
    if(dep[x]<dep[y])
    {
        if(edge_id[heavy[x]]<edge_id[y])
            res=getval(1,edge_id[heavy[x]],edge_id[y]);
        else res=getval(1,edge_id[y],edge_id[heavy[x]]);
    }
    if(dep[x]>dep[y])
    {
        if(edge_id[heavy[y]]<edge_id[x])
            res=getval(1,edge_id[heavy[y]],edge_id[x]);
        else res=getval(1,edge_id[x],edge_id[heavy[y]]);
    }
    if(res>ans)ans=res;
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        init();
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n-1; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            G[x].push_back(edge(y,i,z));
            G[y].push_back(edge(x,i,z));
        }
        dfs(1,0,1);
        slpf(1,0,1);
        for(int i=1; i<=n; i++)
            if(pre[i])a[edge_id[i]]=val[i];
        build(1,1,n-1);
        while(1)
        {
            char op[10];
            int x,y;
            scanf("%s",op);
            if(op[0]=='D')break;
            scanf("%d%d",&x,&y);
            if(op[0]=='Q')printf("%d\n",getmax(x,y));
            if(op[0]=='C')update(1,edge_id[ith[x]],y);
        }
        printf("\n");
        for(int i=1; i<=n; i++)
            G[i].clear();
    }
    return 0;
}

题目链接:Aragorn's Story

树链剖分(权值在点上)[区间修改 询问单点值]:
struct node
{
    int tl,tr,lazy,sum;
    node():lazy(0),sum(0) {}
}tree[200020];

int a[50005];

void pushup(int id)
{
    tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
}

void build(int id,int tl,int tr)
{
    tree[id].tl=tl,tree[id].tr=tr;
    tree[id].lazy=tree[id].sum=0;
    if(tl==tr)tree[id].sum=a[tl];
    else
    {
        int tm=(tr+tl)>>1;
        build(id<<1,tl,tm);
        build(id<<1|1,tm+1,tr);
        pushup(id);
    }
}

void pushdown(int id)
{
    if(!tree[id].lazy)return;
    tree[id<<1].lazy+=tree[id].lazy;
    tree[id<<1|1].lazy+=tree[id].lazy;
    tree[id<<1].sum+=(tree[id<<1].tr-tree[id<<1].tl+1)*tree[id].lazy;
    tree[id<<1|1].sum+=(tree[id<<1|1].tr-tree[id<<1|1].tl+1)*tree[id].lazy;
    tree[id].lazy=0;
}

void update(int id,int ql,int qr,int val)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql>tr || qr<tl)return;
    if(ql<=tl && tr<=qr)
    {
        tree[id].lazy+=val;
        tree[id].sum+=(tr-tl+1)*val;
        return;
    }
    pushdown(id);
    update(id<<1,ql,qr,val);
    update(id<<1|1,ql,qr,val);
    pushup(id);
}

int get_sum(int id,int ql,int qr)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql>tr || qr<tl)return 0;
    if(ql<=tl && tr<=qr)return tree[id].sum;
    int ans=0;
    pushdown(id);
    ans+=get_sum(id<<1,ql,qr);
    ans+=get_sum(id<<1|1,ql,qr);
    pushup(id);
    return ans;
}

int pre[50005],siz[50005],dep[50005];
int top[50005],node_id[50005],heavy[50005];
int val[50005],idx=0;
vector<int>G[50005];

int dfs(int x,int fa,int depth)
{
    dep[x]=depth,pre[x]=fa;
    int res=1,maxx=0;
    int len=G[x].size();
    for(int i=0; i<len; i++)
    {
        if(G[x][i]==fa)continue;
        int t=dfs(G[x][i],x,depth+1);
        if(t>maxx)maxx=t,heavy[x]=G[x][i];
        res+=t;
    }
    return siz[x]=res;
}

void slpf(int x,int fa,int tp)
{
    node_id[x]=++idx,top[x]=tp;
    int len=G[x].size();
    if(heavy[x])slpf(heavy[x],x,tp);
    for(int i=0; i<len; i++)
    {
        int nex=G[x][i];
        if(nex==fa)continue;
        if(nex!=heavy[x])slpf(nex,x,nex);
    }
}

void change(int x,int y,int z)
{
    while(top[x]!=top[y])
    {
        if(dep[top[x]]>dep[top[y]])
        {
            update(1,node_id[top[x]],node_id[x],z);
            x=pre[top[x]];
        }
        else
        {
            update(1,node_id[top[y]],node_id[y],z);
            y=pre[top[y]];
        }
    }
    if(dep[x]>dep[y])swap(x,y);
    update(1,node_id[x],node_id[y],z);
}

void init(void)
{
    idx=0;
    memset(a,0,sizeof(a));
    memset(val,0,sizeof(val));
    memset(top,0,sizeof(top));
    memset(pre,0,sizeof(pre));
    memset(siz,0,sizeof(siz));
    memset(dep,0,sizeof(dep));
    memset(heavy,0,sizeof(heavy));
    memset(tree,0,sizeof(tree));
    memset(node_id,0,sizeof(node_id));
}

int main()
{
    int n,m,q;
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        init();
        for(int i=1;i<=n;i++)
            scanf("%d",&val[i]);
        for(int i=1;i<=m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        dfs(1,0,1);
        slpf(1,0,1);
        for(int i=1;i<=n;i++)
            a[node_id[i]]=val[i];
        build(1,1,n);
        while(q--)
        {
            char op[2];int x,y,z;
            scanf("%s",op);
            if(op[0]=='I')
            {
                scanf("%d%d%d",&x,&y,&z);
                change(x,y,z);
            }
            if(op[0]=='D')
            {
                scanf("%d%d%d",&x,&y,&z);
                change(x,y,-z);
            }
            if(op[0]=='Q')
            {
                scanf("%d",&x);
                printf("%d\n",get_sum(1,node_id[x],node_id[x]));
            }
        }
        for(int i=1;i<=n;i++)G[i].clear();
    }
    return 0;
}

题目链接:软件包管理器

树链剖分(权值在点上)[区间修改 询问区间和]:
struct node
{
    int tl,tr,lazy,sum;
    node():lazy(-1),sum(0) {}
}tree[400020];

inline void pushup(int id)
{
    tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
}

void build(int id,int tl,int tr)
{
    tree[id].tl=tl,tree[id].tr=tr;
    if(tl==tr)tree[id].lazy=-1;
    else
    {
        int tm=(tr+tl)>>1;
        build(id<<1,tl,tm);
        build(id<<1|1,tm+1,tr);
        pushup(id);
    }
}

void pushdown(int id)
{
    if(tree[id].lazy==-1)return;
    tree[id<<1].lazy=tree[id].lazy;
    tree[id<<1|1].lazy=tree[id].lazy;
    tree[id<<1].sum=(tree[id<<1].tr-tree[id<<1].tl+1)*tree[id].lazy;
    tree[id<<1|1].sum=(tree[id<<1|1].tr-tree[id<<1|1].tl+1)*tree[id].lazy;
    tree[id].lazy=-1;
}

void update(int id,int ql,int qr,int val)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql>tr || qr<tl)return;
    if(ql<=tl && tr<=qr)
    {
        tree[id].lazy=val;
        tree[id].sum=(tr-tl+1)*val;
        return;
    }
    pushdown(id);
    update(id<<1,ql,qr,val);
    update(id<<1|1,ql,qr,val);
    pushup(id);
}

int get_sum(int id,int ql,int qr)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql>tr || qr<tl)return 0;
    if(ql<=tl && tr<=qr)return tree[id].sum;
    int ans=0;
    pushdown(id);
    ans+=get_sum(id<<1,ql,qr);
    ans+=get_sum(id<<1|1,ql,qr);
    pushup(id);
    return ans;
}

int uninall(int id,int ql,int qr)
{
    int tl=tree[id].tl,tr=tree[id].tr;
    if(ql>tr || qr<tl)return 0;
    if(ql<=tl && tr<=qr)
    {
        int ans=tree[id].sum;
        tree[id].lazy=0;
        tree[id].sum=0;
        return ans;
    }
    int ans=0;
    pushdown(id);
    ans+=uninall(id<<1,ql,qr);
    ans+=uninall(id<<1|1,ql,qr);
    pushup(id);
    return ans;
}

int pre[100005],siz[100005],dep[100005];
int top[100005],node_id[100005],heavy[100005];
int lson[100005],rson[100005],idx=0;

struct
{
    int nex,nex_node;
} edge[100005];

int head[100005],cont=0;

void add_edge(int now,int nex)
{
    edge[cont].nex=nex;
    edge[cont].nex_node=head[now];
    head[now]=cont++;
}

int dfs(int x,int fa,int depth)
{
    dep[x]=depth,pre[x]=fa;
    int res=1,maxx=0;
    for(int i=head[x];~i;i=edge[i].nex_node)
    {
        int nex=edge[i].nex;
        if(nex==fa)continue;
        int t=dfs(nex,x,depth+1);
        if(t>maxx)maxx=t,heavy[x]=nex;
        res+=t;
    }
    return siz[x]=res;
}

void slpf(int x,int fa,int tp)
{
    lson[x]=node_id[x]=++idx;
    top[x]=tp;
    if(heavy[x])slpf(heavy[x],x,tp);
    for(int i=head[x];~i;i=edge[i].nex_node)
    {
        int nex=edge[i].nex;
        if(nex==fa)continue;
        if(nex!=heavy[x])slpf(nex,x,nex);
    }
    rson[x]=idx;
}

int getsum(int x,int y,int z)
{
    int ans=0,res;
    while(top[x]!=top[y])
    {
        if(dep[top[x]]>dep[top[y]])
        {
            res=get_sum(1,node_id[top[x]],node_id[x]);
            update(1,node_id[top[x]],node_id[x],z);
            x=pre[top[x]];
        }
        else
        {
            res=get_sum(1,node_id[top[y]],node_id[y]);
            update(1,node_id[top[y]],node_id[y],z);
            y=pre[top[y]];
        }
        ans+=res;
    }
    if(dep[x]>dep[y])swap(x,y);
    res=get_sum(1,node_id[x],node_id[y]);
    update(1,node_id[x],node_id[y],z);
    ans+=res;
    return ans;
}

int main()
{
    memset(head,-1,sizeof(head));
    int n,t;
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
    {
        scanf("%d",&t);
        add_edge(t+1,i);
    }
    dfs(1,0,1);
    slpf(1,0,1);
    build(1,1,n);
    int q;
    scanf("%d",&q);
    while(q--)
    {
        char op[15];int x;
        scanf("%s%d",op,&x);
        if(op[0]=='i')
        {
            int res=getsum(x+1,1,1);
            printf("%d\n",dep[x+1]-res);
        }
        else
        {
            int res=uninall(1,lson[x+1],rson[x+1]);
            printf("%d\n",res);
        }
    }
    return 0;
}


作者:fo0Old
链接:http://www.jianshu.com/p/03f365028725
來源:简书
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值