ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

九省联考2018

2019-09-07 14:58:17  阅读:183  来源: 互联网

标签:return val int Tree mid 九省 2018 联考 dp


一双木棋

chess 搜索,在搜索的过程中使用哈希记录重复的状态,每一次枚举合法的放置位置往下递归,取当前所有可行状态中的最优解即可。
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

inline int read(){
    int a = 0;
    char c = getchar();
    while(!isdigit(c))
        c = getchar();
    while(isdigit(c)){
        a = a * 10 + c - 48;
        c = getchar();
    }
    return a;
}

#define ll long long
#define PII pair < int , int >
#define st first
#define nd second
unordered_map < ll , PII > Hash;
int st[11] , A[11][11] , B[11][11] , N , M;

ll get(){
    ll hash = 0;
    for(int i = 1 ; i <= M ; ++i)
        hash = hash * 11 + st[i];
    return hash;
}

PII dfs(int cnt){
    if(cnt == N * M)
        return PII(0 , 0);
    ll zt = get();
    if(Hash.find(zt) != Hash.end())
        return Hash[zt];
    PII Max = PII(0 , 0);
    int now = -1e9;
    for(int i = 1 ; i <= M ; ++i)
        if(st[i] < st[i - 1]){
            ++st[i]; PII t = dfs(cnt + 1);
            !(cnt & 1) ? t.st += A[st[i]][i] : t.nd += B[st[i]][i];
            int del = !(cnt & 1) ? t.st - t.nd : t.nd - t.st;
            if(now < del){
                now = del;
                Max = t;
            }
            --st[i];
        }
    return Hash[zt] = Max;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    //freopen("out","w",stdout);
#endif
    N = read(); M = read();
    for(int i = 1 ; i <= N ; ++i)
        for(int j = 1 ; j <= M ; ++j)
            A[i][j] = read();
    for(int i = 1 ; i <= N ; ++i)
        for(int j = 1 ; j <= M ; ++j)
            B[i][j] = read();
    st[0] = N;
    PII t = dfs(0);
    cout << t.st - t.nd;
    return 0;
}

IIIDX

IIIDX 把没有父亲的点的父亲看作$0$,这样原来的依赖关系就形成了一棵树。

有一个显然的满足$d$不相同时的贪心:按照bfs序贪心选择每个点的权值。对于点$x$,$fa_x$中有一些权值可以使用,它一定会选择这些权值中第$sz_x$大的权值作为自己的权值,并使这些权值中的第$1 \sim sz_x-1$大的权值作为它的子树中所有点的权值。

但是在有权值相同时这样的贪心就不一定正确了,因为有可能$sz_x+1$大的元素与$sz_x$大的元素相等,也就是说有可能取其中$1 \sim sz_x-1$大不一定更优。

我们考虑每一个点,设$f_x$表示对于之前的所有点来说,至少有多少个数$\geq x$才能够在之后的选择中存在方案,又设$p_x$表示序列$d$的所有数中$\geq x$的数的个数。

那么如果当前点$q$能够选择$x$作为自身权值,那么一定要满足$\forall y \leq x , f_y + sz_q \leq p_y$,即$p_y - f_y \geq sz_q$。在线段树上维护$p_y - f_y$的最小值就可以二分出$x$的最大值。然后在线段树上对$\forall i \in [1,x] , f_i += sz_y$表示当前点$y$占用了$sz_y$个$\geq x$的数。不难证明上述条件是充要的。

注意如果现在考虑到了点$p$,那么我们需要去掉$fa_p$的子树对$f$数组的影响,因为我们现在正在考虑$fa_p$的子树,所以$fa_p$的子树之前占用的部分就可以释放出来留给子树进行选择了。
#include<bits/stdc++.h>
using namespace std;

#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)
const int _ = 5e5 + 3;
int fa[_] , sz[_] , val[_] , tmp[_] , ans[_] , N; double K; bool fr[_];
namespace segt{
    int mrk[_ << 2] , mn[_ << 2];

    void mark(int x , int val){mrk[x] += val; mn[x] += val;}
    void down(int x){mark(lch , mrk[x]); mark(rch , mrk[x]); mrk[x] = 0;}
    void up(int x){mn[x] = min(mn[lch] , mn[rch]);}
    
    void modify(int x , int l , int r , int L , int R , int num){
        if(l >= L && r <= R){mn[x] += num; mrk[x] += num; return;}
        down(x);
        if(mid >= L) modify(lch , l , mid , L , R , num);
        if(mid < R) modify(rch , mid + 1 , r , L , R , num);
        up(x);
    }

    int qry(int x , int l , int r , int val){
        if(l == r) return l - (mn[x] >= val);
        down(x);
        return mn[rch] >= val ? qry(lch , l , mid , val) : qry(rch , mid + 1 , r , val);
    }
}

int main(){
    ios::sync_with_stdio(0); cin >> N >> K;
    for(int i = 1 ; i <= N ; ++i) cin >> val[i];
    sort(val + 1 , val + N + 1 , [&](int a , int b){return a > b;});
    memcpy(tmp , val , sizeof(tmp)); int cnt = unique(val + 1 , val + N + 1) - val - 1;
    for(int i = 1 ; i <= N ; ++i)
        segt::modify(1 , 1 , cnt , lower_bound(val + 1 , val + cnt + 1 , tmp[i] , [&](int a , int b){return a > b;}) - val , cnt , 1);
    for(int i = N ; i ; --i) sz[fa[i] = i / K] += ++sz[i];
    fr[0] = 1;
    for(int i = 1 ; i <= N ; ++i){
        if(!fr[fa[i]]){
            fr[fa[i]] = 1;
            segt::modify(1 , 1 , cnt , ans[fa[i]] , cnt , sz[fa[i]] - 1);
        }
        ans[i] = segt::qry(1 , 1 , cnt , sz[i]) + 1;
        segt::modify(1 , 1 , cnt , ans[i] , cnt , -sz[i]);
    }
    for(int i = 1 ; i <= N ; ++i) printf("%d " ,  val[ans[i]]);
    return 0;
}

秘密袭击

coat 题意相当于$\sum\limits_S kth\ of\ S$,其中$S$是个连通块。考虑计算$f_x=\sum\limits_S [kth\ of\ S \geq x]$,答案就是$\sum\limits_{i=1}^W i(f_i - f_{i+1})$。

枚举$x$,注意到$f_x = \sum\limits_S [(\sum\limits_{p \in S} [d_p \geq x]) \geq k]$,故设$val_p = [d_p \geq x]$,那么就是需要求连通块权值大于等于$k$的连通块个数。

考虑树形背包,设$f_{i,j}$表示选择了一个以点$i$为深度最浅的点的连通块,连通块点权之和为$j$的方案数。根据经典的背包套路每一次可以做到$O(nk)$。

这样程序的复杂度就是$O(nk(n-k))$,看起来可以过实际上也可以过,比正解好写到不知道哪里去了
#include<bits/stdc++.h>
using namespace std;

#define int long long
const int _ = 2003 , MOD = 64123;
int dp[_][_] , val[_] , lsh[_] , sz[_] , N , K , W;
vector < int > ch[_];

void dfs(int x , int p , int c){
    memset(dp[x] , 0 , sizeof(int) * (K + 1));
    dp[x][sz[x] = val[x] >= c] = 1;
    for(auto t : ch[x])
        if(t != p){
            dfs(t , x , c);
            for(int i = min(sz[x] , K) ; i >= 0 ; --i){
                int p = dp[x][i];
                for(int j = min(sz[t] , K) ; j >= 0 ; --j)
                    dp[x][min(i + j , K)] = (dp[x][min(i + j , K)] + p * dp[t][j]) % MOD;
            }
            sz[x] += sz[t];
        }
}

signed main(){
    cin >> N >> K >> W; for(int i = 1 ; i <= N ; ++i) cin >> val[i];
    for(int i = 1 ; i < N ; ++i){
        int a , b; cin >> a >> b;
        ch[a].push_back(b); ch[b].push_back(a);
    }
    for(int i = 1 ; i <= N ; ++i) lsh[i] = val[i];
    sort(lsh + 1 , lsh + N + 1); int pre = 0 , ans = 0;
    for(int i = N - K + 1 ; i ; --i)
        if(i == N - K + 1 || lsh[i] != lsh[i + 1]){
            dfs(1 , 0 , lsh[i]); int sum = 0;
            for(int j = 1 ; j <= N ; ++j) sum = (sum + dp[j][K]) % MOD;
            ans = (ans + lsh[i] * (sum - pre + MOD)) % MOD;
            pre = sum;
        }
    cout << ans;
    return 0;
}

劈配

mentor 注意到这是一个劈配匹配问题。

对于第一问,我们枚举每一个人、枚举他实际的录取志愿,考虑是否存在一种方案。这是一个匹配问题,使用网络瘤求解。对所有人将他们向其对应录取志愿的所有导师连$1$边,源点向每个人连$1$边,每个导师向汇点连最大人数边,跑一边瘤,如果最大瘤量等于在当前考虑的人前面的所有人中能够获得导师的人的数量+1则表示当前方案可行。

当然枚举有些慢,可以使用二分计算出实际的录取志愿。

对于第二问,使用和第一问相似的思路。二分位置,把在这个位置之前的所有人和当前这个人对应的边放到网络里跑一边瘤,如果最大瘤量等于在当前位置之前的所有人中能够获得导师的人的数量+1则当前位置可行。
#include<bits/stdc++.h>
using namespace std;

int read(){int a; cin >> a; return a;}

namespace flow{
    const int __ = 1e6 + 7 , _ = 1e5 + 7;
    struct Edge{int end , upEd , f;}Ed[__];
    int cur[_] , head[_] , dep[_] , cntEd , S , T;
    queue < int > q;

    void addEd(int a , int b , int c){Ed[++cntEd] = (Edge){b , head[a] , c}; head[a] = cntEd;}
    void addE(int a , int b , int c){addEd(a , b , c); addEd(b , a , 0);}
    
    bool bfs(){
        while(!q.empty()) q.pop(); q.push(S);
        memset(dep , 0 , sizeof(int) * (T + 1)); dep[S] = 1;
        while(!q.empty()){
            int t = q.front(); q.pop();
            for(int i = head[t] ; i ; i = Ed[i].upEd)
                if(!dep[Ed[i].end] && Ed[i].f){
                    dep[Ed[i].end] = dep[t] + 1; q.push(Ed[i].end);
                    if(Ed[i].end == T){
                        memcpy(cur , head , sizeof(int) * (T + 1));
                        return 1;
                    }
                }
        }
        return 0;
    }
    
    int dfs(int x , int mn){
        if(x == T) return mn;
        int sum = 0;
        for(int &i = cur[x] ; i ; i = Ed[i].upEd)
            if(Ed[i].f && dep[Ed[i].end] == dep[x] + 1){
                int t = dfs(Ed[i].end , min(Ed[i].f , mn - sum));
                sum += t; Ed[i].f -= t; Ed[i ^ 1].f += t;
                if(sum == mn) break;
            }
        return sum;
    }

    int Dinic(int s , int t){S = s; T = t; int sum = 0; while(bfs()) sum += dfs(S , 1e9); return sum;}
    void clear(){memset(head , 0 , sizeof(int) * (T + 1)); cntEd = 1;}
}using flow::addE;

int T , N , M , B[203] , to[203] , ans[203]; vector < int > need[203][203];

int main(){
    for(T = read() , read() ; T ; --T){
        N = read(); M = read();
        for(int i = 1 ; i <= M ; ++i) B[i] = read();
        for(int i = 1 ; i <= N ; ++i)
            for(int j = 1 ; j <= M + 1 ; ++j)
                need[i][j].clear();
        for(int i = 1 ; i <= N ; ++i)
            for(int j = 1 ; j <= M ; ++j)
                need[i][read()].push_back(j);
        for(int i = 1 ; i <= N ; ++i) to[i] = read();
        for(int i = 1 ; i <= N ; ++i){
            int L = 1 , R = M + 1;
            while(L < R){
                int mid = (L + R) >> 1 , cnt = 1; flow::clear();
                for(int j = 1 ; j < i ; ++j)
                    if(ans[j] != M + 1){
                        addE(0 , j , 1); ++cnt;
                        for(int k = 0 ; k < need[j][ans[j]].size() ; ++k)
                            addE(j , need[j][ans[j]][k] + N , 1);
                    }
                addE(0 , i , 1);
                for(int j = 1 ; j <= mid ; ++j)
                    for(int k = 0 ; k < need[i][j].size() ; ++k)
                        addE(i , need[i][j][k] + N , 1);
                for(int j = 1 ; j <= M ; ++j) addE(j + N , N + M + 1 , B[j]);
                flow::Dinic(0 , N + M + 1) == cnt ? R = mid : L = mid + 1;
            }
            printf("%d%c" , ans[i] = L , " \n"[i == N]);
        }
        for(int i = 1 ; i <= N ; ++i)
            if(ans[i] <= to[i]) printf("0%c" , " \n"[i == N]);
            else{
                int L = 0 , R = i - 1;
                while(L < R){
                    int mid = (L + R + 1) >> 1 , cnt = 1; flow::clear();
                    for(int j = 1 ; j < mid ; ++j)
                        if(ans[j] != M + 1){
                            addE(0 , j , 1); ++cnt;
                            for(int k = 0 ; k < need[j][ans[j]].size() ; ++k)
                                addE(j , need[j][ans[j]][k] + N , 1);
                        }
                    addE(0 , i , 1);
                    for(int j = 1 ; j <= to[i] ; ++j)
                        for(int k = 0 ; k < need[i][j].size() ; ++k)
                            addE(i , need[i][j][k] + N , 1);
                    for(int j = 1 ; j <= M ; ++j) addE(j + N , N + M + 1 , B[j]);
                    flow::Dinic(0 , N + M + 1) == cnt ? L = mid : R = mid - 1;
                }
                printf("%d%c" , i - L , " \n"[i == N]);
            }
    }
    return 0;
}

林克卡特树

lct 题目等价于选出$k+1$条点不重复的路径使得边权和最大。

对于$k \leq 100$的部分考虑树形背包:设$f_{i,j,0/1/2}$表示点$i$的子树内有$j$条路径,点$i$向下与$0/1/2$个儿子有连边的最大权值和。转移枚举儿子考虑是否连边。有三个细节:可能存在$f_{i,j,0}$作为一条链起始的情况;两条链合并在一起的时候路径数量会$-1$;$1$号点可能单独作为一条路径。

然后打表可以发现设$g_j$表示$k=j$时的答案,那么$g_j$是一个凸函数,即$g_j - g_{j-1} \geq g_{j+1} - g_j$,也就是差分之后数组单调递减。

设差分之后的数组为$p_x = g_x - g_{x-1}$,我们考虑二分$p_{k+1}$的值。设当前二分到$mid$,考虑给所有$p_x -= mid(x \geq 1)$,如果$mid = p_{k+1}$,则新的$g_k$和$g_{k+1}$都会是数列极值。而当$mid$增大的时候,新的数列的极值点在变小,满足单调性。所以二分可行。

对于所有$p_x -= mid$相当于给$g_x -= x \times mid$,在原问题中相当于选择一条路径产生$mid$的代价。这个部分在$k \leq 100$的背包中可简单进行贡献。而二分后背包部分不会受到路径条数限制,所以背包$j$维可以删掉,只需要在背包的每个状态记录到达当前最大贡献的路径条数即可。

这样总复杂度就是$O(nlog(nw))$,可以通过所有数据。
#include<bits/stdc++.h>
using namespace std;

int read(){int a; scanf("%d" , &a); return a;}

#define PII pair < long long , int >
const int _ = 3e5 + 7;
PII dp[_][3]; int N , K , val; vector < PII > ch[_];

PII max(PII A , PII B){return A.first > B.first ? A : (A.first == B.first && A.second < B.second ? A : B);}
PII operator +(PII A , PII B){return PII(A.first + B.first , A.second + B.second);}

void dfs(int x , int p){
    dp[x][0] = PII(0 , 0); dp[x][1] = PII(-1e18 , 0); dp[x][2] = PII(val , 1);
    for(auto t : ch[x])
        if(t.first != p){
            dfs(t.first , x);
            PII v2 = max(max(dp[t.first][0] , dp[t.first][1]) , dp[t.first][2]);
            PII v = max(dp[t.first][1] , dp[t.first][0] + PII(val , 1));
            dp[x][2] = max(dp[x][2] + v2 , dp[x][1] + v + PII(t.second - val , -1));
            dp[x][1] = max(dp[x][1] + v2 , dp[x][0] + v + PII(t.second , 0));
            dp[x][0] = dp[x][0] + v2;
        }
}

int main(){
    freopen("lct.in","r",stdin); freopen("lct.out","w",stdout);
    N = read(); K = read();
    for(int i = 1 ; i < N ; ++i){
        int a = read() , b = read() , c = read();
        ch[a].emplace_back(b , c); ch[b].emplace_back(a , c);
    }
    long long L = -1e12 , R = 1e12;
    while(L < R){
        int mid = (L + R) >> 1; val = -mid; dfs(1 , 0);
        max(max(dp[1][0] , dp[1][1]) , max(dp[1][2] , dp[1][0] + PII(val , 1))).second < K + 1 ? R = mid : L = mid + 1;
    }
    val = -L; dfs(1 , 0); cout << max(max(dp[1][0] , dp[1][1]) , max(dp[1][2] , dp[1][0] + PII(val , 1))).first + (K + 1) * L;
    return 0;
}

制胡窜

cutting 让我酝酿一下题解怎么写……这个题细节比较毒瘤
#include<bits/stdc++.h>
//This code is written by Itst
using namespace std;

inline int read(){
    int a = 0;
    char c = getchar();
    while(!isdigit(c))
        c = getchar();
    while(isdigit(c)){
        a = a * 10 + c - 48;
        c = getchar();
    }
    return a;
}

#define int long long
const int MAXN = 1e5 + 7;
int N , Q , ind[MAXN];
char s[MAXN];

struct DATA{
    int minN , maxN , sum;
    DATA(){maxN = sum = 0; minN = 1e9;}
};

namespace segTree{
    struct node{
        int l , r;
        DATA data;
    }Tree[MAXN * 80];
    int cntN;
    
#define mid ((l + r) >> 1)
#define lch Tree[x].l
#define rch Tree[x].r

    inline DATA pushup(DATA x , DATA y){
        DATA t;
        t.minN = min(x.minN , y.minN);
        t.maxN = max(x.maxN , y.maxN);
        t.sum = x.sum + y.sum + (x.maxN && y.minN != 1e9 ? (y.minN - x.maxN) * y.minN : 0);
        return t;
    }
    
    int modify(int x , int l , int r , int tar){
        int t = ++cntN;
        Tree[t] = Tree[x];
        if(l == r){
            Tree[t].data.minN = Tree[t].data.maxN = tar;
            return t;
        }
        if(mid >= tar) Tree[t].l = modify(Tree[t].l , l , mid , tar);
        else Tree[t].r = modify(Tree[t].r , mid + 1 , r , tar);
        Tree[t].data = pushup(Tree[Tree[t].l].data , Tree[Tree[t].r].data);
        return t;
    }
    
    int merge(int x , int y){
        if(!x || !y) return x + y;
        int t = ++cntN;
        Tree[t].l = merge(Tree[x].l , Tree[y].l);
        Tree[t].r = merge(Tree[x].r , Tree[y].r);
        Tree[t].data = pushup(Tree[Tree[t].l].data , Tree[Tree[t].r].data);
        return t;
    }

    DATA query(int x , int l , int r , int L , int R){
        if(L > R) return DATA();
        if(l >= L && r <= R) return Tree[x].data;
        DATA t;
        if(mid >= L) t = pushup(t , query(lch , l , mid , L , R));
        if(mid < R) t = pushup(t , query(rch , mid + 1 , r , L , R));
        return t;
    }

    int qMax(int x , int l , int r , int tar){
        if(l == r) return Tree[x].data.maxN;
        if(mid >= tar) return qMax(Tree[x].l , l , mid , tar);
        return max(Tree[Tree[x].l].data.maxN , qMax(Tree[x].r , mid + 1 , r , tar));
    }

    int qMin(int x , int l , int r , int tar){
        if(l == r) return Tree[x].data.minN;
        if(mid >= tar) return min(Tree[Tree[x].r].data.minN , qMin(Tree[x].l , l , mid , tar));
        return qMin(Tree[x].r , mid + 1 , r , tar);
    }
}
using segTree::modify; using segTree::qMax; using segTree::qMin; using segTree::merge;

namespace SAM{
    int trans[MAXN << 1][10] , fa[MAXN << 1] , Len[MAXN << 1] , endpos[MAXN << 1];
    int cnt = 1 , lst = 1;
    vector < int > ch[MAXN << 1];
    int rt[MAXN << 1] , jump[MAXN << 1][20];

    int insert(int l , int x){
        int t = ++cnt , p = lst;
        lst = t; endpos[t] = l; Len[t] = l;
        while(p && !trans[p][x]){
            trans[p][x] = t;
            p = fa[p];
        }
        if(!p){fa[t] = 1; return t;}
        int q = trans[p][x];
        if(Len[q] == Len[p] + 1){fa[t] = q; return t;}
        int k = ++cnt; Len[k] = Len[p] + 1;
        memcpy(trans[k] , trans[q] , sizeof(trans[q]));
        fa[k] = fa[q]; fa[q] = fa[t] = k;
        while(trans[p][x] == q){
            trans[p][x] = k;
            p = fa[p];
        }
        return t;
    }
    
    void dfs(int x , int p){
        jump[x][0] = p;
        for(int i = 1 ; jump[x][i - 1] ; ++i)
            jump[x][i] = jump[jump[x][i - 1]][i - 1];
        for(auto t : ch[x]){
            dfs(t , x);
            rt[x] = merge(rt[x] , rt[t]);
        }
        if(endpos[x])
            rt[x] = modify(rt[x] , 1 , N , endpos[x]);
    }
    
    void init(){
        for(int i = 2 ; i <= cnt ; ++i)
            ch[fa[i]].push_back(i);
        dfs(1 , 0);
    }

    int Jump(int x , int len){
        for(int i = 18 ; i >= 0 ; --i)
            if(Len[jump[x][i]] >= len)
                x = jump[x][i];
        return x;
    }

#define calc2(x) ((x) * (x - 1) / 2)
    int query(int x , int len){
        if(len == 1) return calc2(N - 1);
        DATA p = segTree::Tree[rt[x]].data;
        int l1 = p.minN - len + 1 , r1 = p.minN , lm = p.maxN - len + 1 , rm = p.maxN;
        if(lm < r1)
            return calc2(N - 1) - (l1 - 1) * (r1 - lm) - (p.sum - (rm - r1) * lm) - (calc2(N - lm) - calc2(N - r1));
        int mL = qMax(rt[x] , 1 , N , r1 + len - 2) , mR = qMin(rt[x] , 1 , N , lm + 1);
        if(mL < mR)
            if(segTree::query(rt[x] , 1 , N , mL + 1 , mR - 1).maxN) return calc2(N - 1);
            else return calc2(N - 1) - (r1 - (mL - len + 1)) * (mR - lm);
        DATA q = segTree::query(rt[x] , 1 , N , mR , mL);
        mL = qMin(rt[x] , 1 , N , mL + 1); mR = qMax(rt[x] , 1 , N , mR - 1);
        return calc2(N - 1) - (q.sum - (q.maxN - q.minN) * lm) - (r1 - (q.maxN - len + 1)) * (mL - lm) - (q.minN - mR) * (q.minN - lm);
    }
}

signed main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    N = read(); Q = read();
    scanf("%s" , s + 1);
    for(int i = 1 ; i <= N ; ++i)
        ind[i] = SAM::insert(i , s[i] - '0');
    SAM::init();
    while(Q--){
        int l = read() , r = read();
        printf("%lld\n" , SAM::query(SAM::Jump(ind[r] , r - l + 1) , r - l + 1));
    }
    return 0;
}

标签:return,val,int,Tree,mid,九省,2018,联考,dp
来源: https://www.cnblogs.com/Itst/p/11480757.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有