2019 ICPC Asia Xuzhou Regional

Contest Info


Practice Link

Solved A B C D E F G H I J K L M
8/13 O - O - O O - O - O - O O
  • O 在比赛中通过
  • Ø 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. Cat

题意:
每次询问给出\(L, R, S\),要求找一个最长的连续区间\(l, r\),满足\(l \oplus (l + 1) \oplus, \cdots, \oplus r <= S\)

思路:
考虑\(4k \oplus (4k + 1) \oplus (4k + 2) \oplus (4k +3) = 0\)
那么我们枚举一下头,枚举一下尾,暴力判断一下即可。

代码:


view code

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const ll INF = 0x3f3f3f3f3f3f3f3f;

ll L, R, S;

ll gao(ll l, ll r) {
    if (l > r) return INF;
    ll res = 0;
    if (r - l + 1 <= 10) {
        for (ll i = l; i <= r; ++i) {
            res ^= i;
        }
    } else {
        ll ql = l, qr = r;
        while (ql % 4 != 0) {
            res ^= ql;
            ql++;
        }
        while (qr % 4 != 3) {
            res ^= qr;
            qr--;
        }
    }
    return res;
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        scanf("%lld %lld %lld", &L, &R, &S);
        ll res = -1;
        for (int i = 0; i <= 4; ++i) {
            for (int j = 0; j <= 4; ++j) {
                ll tmp = gao(L + i, R - j);
                if (tmp <= S) res = max(res, (R - j) - (L + i) + 1);
            }
        }
        printf("%lld\n", res);
    }
    return 0;
}

B. Cats line up

题意:
给出\(n\)个数,问有多少个排列使得任意相邻两个数的差距小于等于\(K(1 \leq K \leq 3)\)

C. <3 numbers

题意:
\(x\)为区间\([L, R]\)内素数个数,每次询问给出\([L, R]\),判断下式是否成立:
\[ \begin{eqnarray*} \frac{x}{R - L + 1} < \frac{1}{3} \end{eqnarray*} \]

思路:
考虑素数密度,大区间直接'Yes'
小区间暴力判断

代码:


view code

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int L, R, pri[N], check[N];
void sieve() {
    memset(check, 0, sizeof check);
    for (int i = 2; i < N; ++i) {
        if (!check[i]) {
            pri[++*pri] = i;
        }
        for (int j = 1; j <= *pri; ++j) {
            if (1ll * i * pri[j] >= N) break;
            check[i * pri[j]] = 1;
            if (i % pri[j] == 0) break;
        }
    }
}

bool prime(int x) {
    if (x < N) return !check[x];
    for (int i = 2; 1ll * i * i <= x; ++i) {
        if (x % i == 0)
            return false;
    }
    return true;
}

bool ok(int l, int r) {
    int tot = r - l + 1;
    int p = 0;
    for (int i = l; i <= r; ++i) {
        if (prime(i)) {
            ++p;
        }
    }
    return p * 3 < tot;
}

int main() {
    sieve();
    int _T; scanf("%d", &_T);
    while (_T--) {
        scanf("%d%d", &L, &R);
        if (R - L + 1 > 60) {
            puts("Yes");
        } else {
            puts(ok(L, R) ? "Yes" : "No");
        }
    }
    return 0;
}

E. Multiply

题意:
给出\(n\)个数\(a_i\),令\(Z = a_1! \times a_2! \times \cdots \times a_n!\)
现在给出\(X, Y\),令\(b_i = Z \times X^i\),它想要一个最大的\(i\),使得\(b_i \;|\; Y!\)

思路:
考虑分解\(X\)得到它的所有素因子及幂次。
然后找出其每个因子在\(\frac{Y!}{Z}\)中还剩多少个。
然后贪心拼\(X\)就可以了

代码:


view code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
int n; ll x, y, a[N], f[N];
mt19937 rd(time(0));
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
//ll mul(ll a, ll b, ll p) {
//  return (a * b - (ll)(a / (long double)p * b + 1e-3) * p + p) % p;
//}
ll mul(ll a, ll b, ll p) {
    return (__int128)a * b % p;
}
ll qpow(ll base, ll n, ll p) {
    ll res = 1;
    base %= p;
    while (n) {
        if (n & 1) {
            res = mul(res, base, p);
        }
        base = mul(base, base, p);
        n >>= 1;
    }
    return res;
}

struct Mill {
    ll n, fac[22000][2], bk[22000]; int tot;
    const int C = 2307;
    const int S = 8;
    bool check(ll a, ll n) {
        ll m = n - 1, x, y = 0;
        int j = 0;
        while (!(m & 1)) {
            m >>= 1;
            ++j;
        }
        x = qpow(a, m, n);
        for (int i = 1; i <= j; x = y, ++i) {
            y = mul(x, x, n);
            if (y == 1 && x != 1 && x != n - 1) {
                return 1;
            }
        }
        return y != 1;
    }
    bool miller_rabin(ll n) {
        if (n < 2) {
            return 0;
        } else if (n == 2) {
            return 1;
        } else if (!(n & 1)) {
            return 0;
        }
        for (int i = 0; i < S; ++i) {
            if (check(rd() % (n - 1) + 1, n)) {
                return 0;
            }
        }
        return 1;
    }
    ll pollard_rho(ll n, int c) {
        ll i = 1, k = 2, x = rd() % n, y = x, d;
        while (1) {
            ++i; x = (mul(x, x, n) + c) % n;
            d = gcd(y - x, n);
            if (d > 1 && d < n) {
                return d;
            }
            if (y == x) {
                return n;
            }
            if (i == k) {
                y = x;
                k <<= 1;
            }
        }
    }
    void findfac(ll n, int c) {
        if (n == 1) {
            return;
        }
        if (miller_rabin(n)) {
            bk[++*bk] = n;
            return;
        }
        ll m = n;
        while (m == n) {
            m = pollard_rho(n, c--);
        }
        findfac(m, c);
        findfac(n / m, c);
    }
    void gao(ll _n) {
        n = _n; *bk = 0;
        findfac(n, C);
        sort(bk + 1, bk + 1 + *bk);
        fac[1][0] = bk[1];
        fac[1][1] = 1;
        tot = 1;
        for (int i = 2; i <= *bk; ++i) {
            if (bk[i] == bk[i - 1]) {
                ++fac[tot][1];
            } else {
                ++tot;
                fac[tot][0] = bk[i];
                fac[tot][1] = 1;
            }
        }
    }
}mill;

int main() {
    int _T; cin >> _T;
    while (_T--) {
        scanf("%d%lld%lld", &n, &x, &y);
        for (int i = 1; i <= n; ++i) scanf("%lld", a + i);
        mill.gao(x);
        int tot = mill.tot;
        for (int i = 1; i <= tot; ++i) f[i] = 0;
        ll res = 8e18;
        for (int i = 1; i <= tot; ++i) {
//          dbg(mill.fac[i][0], mill.fac[i][1]);
            ll now = 1;
            for (int j = 1; now <= y / mill.fac[i][0]; ++j) {
                now *= mill.fac[i][0];
                f[i] += (y / now);
                for (int o = 1; o <= n; ++o) {
                    f[i] -= (a[o] / now);
                }
            } 
            res = min(1ll * res, f[i] / mill.fac[i][1]);
        }       
        printf("%lld\n", res);
    }
    return 0;
}

F. The Answer to the Ultimate Question of Life, The Universe, and Everything.

题意:
每次询问给出\(x(0 \leq x \leq 200)\),需要找出\(a, b, c(|a|, |b|, |c| \leq 5000)\)满足\(a^3 + b^3 + c^3 = x\)

思路:
\(x\)只有201个,可以暴力打表。
打表的时候可以枚举两维,第三维直接算。

打表代码:


view code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll ok(ll need) {
    ll l = -5000, r = 5000, res = -12345678;
    while (r - l >= 0) {
        ll mid = (l + r) >> 1;
        ll tmp = mid * mid * mid;
        if (tmp == need) {
            return mid;
        }
        if (tmp > need) {
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    return res;
}

bool gao(int x) {
    int limit = 5000;   
    for (ll a = -limit; a <= limit; ++a) {
        for (ll b = -limit; b <= limit; ++b) {
            ll need = 1ll * x - a * a * a - b * b * b;
            ll c = ok(need);
            if (abs(c) <= 5000) {
                cout << a << " " << b << " " << c << endl;
                return true;
            }
        }
    }
    return false;
}

int main() {
    int cnt = 0;
    int Y = -12345678;
    for (int i = 0; i <= 200; ++i) {
        if (!gao(i)) {
            cout << Y << " " << Y << " " << Y << endl;
        }
    }
    cout << cnt << " " << cnt << " " << cnt << endl; 
    return 0;
}

H. Yuuki and a problem

题意:
给出一个序列\(a_i\),支持两个操作:

  • \(a_x\)改成\(y\)
  • 询问最小的不能被\(a_l \cdots a_r\)里面的数表示出来的正整数

思路:
考虑没有修改操作怎么做:
主席树权值\(i\)表示\(i\)这个数的和.
然后考虑每次递增上去,假设已经能够表示出\([1, x]\)范围的数,那么我们可以将\([1, x + 1]\)范围内还未加入的数加进去。
这个可以在主席树上查。
并且这个加入次数跟斐波那契列类似,不会很多。
那么有修改,就敲个动态主席树

注意不要把vector当参数传下去,空间要给够

代码:


view code

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 2e5 + 10;
int n, m, q, a[N], L[510][510], R[510][510], cl, cr;
inline int lowbit(int x) { return x & -x; }
struct SEG {
    struct node {
        int ls, rs;
        ll sum;
        void init() { ls = rs = sum = 0; }
    }t[N * 80];
    int rt[N], tot;
    ll res;
    int newnode() {
        ++tot;
        t[tot].init();
        return tot;
    }
    void init() { memset(rt, 0, sizeof rt); tot = 0; }
    void update(int &rt, int l, int r, int pos, int v) {
        if (!rt) rt = newnode();
        t[rt].sum += v;
        if (l == r) return;
        int mid = (l + r) >> 1;
        if (pos <= mid) update(t[rt].ls, l, mid, pos, v);
        else update(t[rt].rs, mid + 1, r, pos, v);
    }
    void update(int x, int pos, int v) {
        for (; x <= n; x += lowbit(x)) {
            update(rt[x], 1, m, pos, v); 
        }
    }
    void query(int dep, int l, int r, int ql, int qr) {
        if (ql > qr) return;
        if (l >= ql && r <= qr) {
            for (int i = 1; i <= cl; ++i) res -= t[L[dep][i]].sum;
            for (int i = 1; i <= cr; ++i) res += t[R[dep][i]].sum;
            return;
        }   
        int mid = (l + r) >> 1;
        if (ql <= mid) {
            for (int i = 1; i <= cl; ++i) L[dep + 1][i] = t[L[dep][i]].ls;
            for (int i = 1; i <= cr; ++i) R[dep + 1][i] = t[R[dep][i]].ls;
            query(dep + 1, l, mid, ql, qr);
        } 
        if (qr > mid) {
            for (int i = 1; i <= cl; ++i) L[dep + 1][i] = t[L[dep][i]].rs;
            for (int i = 1; i <= cr; ++i) R[dep + 1][i] = t[R[dep][i]].rs;
            query(dep + 1, mid + 1, r, ql, qr);
        }
    }
}seg;

int main() {
    m = 2e5;
    while (scanf("%d%d", &n, &q) != EOF) {
        for (int i = 1; i <= n; ++i) scanf("%d", a + i);
        seg.init();
        for (int i = 1; i <= n; ++i) {
            seg.update(i, a[i], a[i]); 
        }
        int op, x, y;
        for (int i = 1; i <= q; ++i) {
            scanf("%d%d%d", &op, &x, &y);
            if (op == 1) {
                seg.update(x, a[x], -a[x]);
                a[x] = y;
                seg.update(x, a[x], a[x]); 
            } else {
                --x;
                cl = cr = 0;
                for (int j = x; j; j -= lowbit(j)) {
                    L[0][++cl] = seg.rt[j];
                }
                for (int j = y; j; j -= lowbit(j)) {
                    R[0][++cr] = seg.rt[j];
                }
                ll l = -1, r = 0;
                while (1) {
                    seg.res = 0;
                    seg.query(0, 1, m, min(1ll * m + 1, l + 2), min(1ll * m, r + 1));
                    ll tot = seg.res;
                //  dbg(i, tot, l + 2, r + 1);
                    if (tot == 0) break;
                    l = r;
                    r += tot;
                }
                printf("%lld\n", r + 1);
            }
        }
    }
    return 0;
}

J. Loli, Yen-Jen, and a graph problem

题意:
给出一个完全图,要将这张图分成\(n - 1\)条路径,第\(i\)条路径的长度为\(i\),并且一条边只能存在于一条路径中。

代码:


view code

#include <bits/stdc++.h>

using namespace std;
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << " "; err(args...); }

const int N = 1e3 + 10;

int n;
int e[N][N];
int Max[N];
int now;
vector<vector<int> > vec;

void fix(int x, int y) {
    e[x][y] = e[y][x] = 1;
}

int find(int x) {
    while (e[Max[x]][x]) {
        ++Max[x];
    }
    return Max[x];
}

void insert(int x) {
    vec[now].push_back(x);
    if ((int)vec[now].size() == now + 1) {
        now--;
        if (now % 2 == 0) vec[now].push_back(x);
    }
}

void gao(int x, int y) {
    insert(x);
    int ny = y + 1;
    if (ny > n) return ;
    insert(ny);
    gao(x + 1, ny);
}

int main() {
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                e[i][j] = (i == j ? 1 : 0);
            }
            Max[i] = 1;
        }
        vec.clear();
        vec.resize(n + 1);
        if (n & 1) {
            for (int cas = n - 1; cas >= 1; --cas) {
                vec[cas].push_back(n);
                int sze = 1;
                while (sze <= cas) {
                    int nxt = find(vec[cas].end()[-1]);
                    fix(vec[cas].end()[-1], nxt);
                    vec[cas].push_back(nxt);
                    sze++;
                }
            }
            for (int i = 1; i < n; ++i) {
                for (int j = 0, sze = vec[i].size(); j < sze; ++j) {
                    printf("%d%c", vec[i][j], " \n"[j == sze - 1]);
                }
            } 
        } else {
            now = n - 1;
        //  insert(2);
        //  gao(1, 2);
            for (int i = 2; i <= n; i += 2) {
                insert(i);
                gao(1, i);
            }
            for (int i = 1; i < n; ++i) {
                for (int j = 0, sze = vec[i].size(); j < sze; ++j) {
                    printf("%d%c", vec[i][j], " \n"[j == sze - 1]);
                }
            }
        }
    }
    return 0;
}

K. K-rectangle

题意:
给出\(n\)个点\((x_i, y_i)(x_i < x_{i + 1}, 0 < y_i)\)
现在你要找若干个矩形覆盖这些点,矩形的底边必须在\(x\)轴上,矩形之间不能有面积交,矩形的花费是\(h(w + k)\)\(h\)为高,\(w\)为宽,\(k\)为给定参数。
求最小花费。

L. Loli, Yen-Jen, and a cool problem

题意:
给出一个Trie,每次询问给出一个\(x_i, L_i\),问有多少个结点为起点向上跳\(L - 1\)步连成的长度为\(L\)的字符串和以\(x_i\)为起点连成的字符串相同
这里的字符在点上,不在边上

思路:
多加一个根节点,就能将点上的字符转化成边上的字符
然后Trie上建SAM,每次查找倍增跳深度最深的合法祖先,它的cnt就是答案

代码:


view code

#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10, ALP = 26, M = 20;
int n, q, trie_pos[N]; char s[N];
struct SAM {
    struct node {
        int maxlen, cnt, fa, nx[ALP];
        void init() { maxlen = cnt = fa = 0; memset(nx, 0, sizeof nx); }
    }t[N << 1];
    int tot, c[N << 1], rk[N << 1], fa[N << 1][M];
    vector <vector<int>> G;
    int newnode() {
        ++tot;
        t[tot].init();
        return tot;
    }
    void init() {
        tot = 0;
        newnode();
    }
    int extend(int id, int lst, int cnt) {
        int cur = newnode(), p;
        t[cur].cnt = cnt;
        t[cur].maxlen = t[lst].maxlen + 1;
        for (p = lst; p && !t[p].nx[id]; p = t[p].fa) t[p].nx[id] = cur;
        if (!p) {
            t[cur].fa = 1;
        } else {
            int q = t[p].nx[id];
            if (t[q].maxlen == t[p].maxlen + 1) {
                t[cur].fa = q;
            } else {
                int clone = newnode();
                t[clone] = t[q];
                t[clone].cnt = 0;
                t[clone].maxlen = t[p].maxlen + 1;
                for (; p && t[p].nx[id] == q; p = t[p].fa) t[p].nx[id] = clone;
                t[cur].fa = t[q].fa = clone; 
            }
        }
        return cur; 
    } 
    void dfs(int u) {
        for (int i = 1; i < M; ++i)
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for (auto &v : G[u]) {
            fa[v][0] = u;
            dfs(v);
            t[u].cnt += t[v].cnt;
        }
    }
    void build() {
        memset(c, 0, sizeof c);
        for (int i = 1; i <= tot; ++i) c[t[i].maxlen]++;
        for (int i = 1; i <= tot; ++i) c[i] += c[i - 1];
//      for (int i = 1; i <= tot; ++i) rk[c[t[i].maxlen]--] = i;
//      for (int i = tot; i; --i) t[t[rk[i]].fa].cnt += t[rk[i]].cnt; 
        G.clear(); G.resize(tot + 1);
        for (int i = 1; i <= tot; ++i) {
            if (t[i].fa) {
                G[t[i].fa].push_back(i); 
            }
        }
        fa[1][0] = 0;
        dfs(1);
    }
    int query(int x, int len) {
        for (int i = M - 1; i >= 0; --i) {
            if (t[fa[x][i]].maxlen >= len) {
                x = fa[x][i];
            }   
        }
        return t[x].cnt;
    }
}sam;

vector <vector<int>> G;
struct Trie {
    struct node {
        int nx[ALP], cnt, sam_pos;
        void init() { memset(nx, 0, sizeof nx); cnt = 0; sam_pos = 0; }
    }t[N];
    int rt, tot;
    int newnode() {
        ++tot;
        t[tot].init();
        return tot;
    }
    void init() { tot = 0; rt = newnode(); }
    int add(int p, int ch) {
        if (!t[p].nx[ch]) {
            t[p].nx[ch] = newnode();
        }
        int now = t[p].nx[ch];
        ++t[now].cnt;
        return now;
    }
    void dfs(int u) {
        for (auto &v : G[u]) {
            trie_pos[v] = add(trie_pos[u], s[v] - 'A');
            dfs(v);
        }
    }
    void bfs() {
        queue <int> q;
        q.push(1);
        t[1].sam_pos = 1;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            for (int i = 0; i < ALP; ++i) {
                if (!t[u].nx[i]) continue;
                int now = t[u].nx[i];
                t[now].sam_pos = sam.extend(i, t[u].sam_pos, t[now].cnt);
                q.push(now);
            }
        }
    }
}trie;

int main() {
    while (scanf("%d%d", &n, &q) != EOF) {
        G.clear(); G.resize(n + 1);
        scanf("%s", s + 1);
        trie.init();
        trie_pos[0] = 1;
        trie_pos[1] = trie.add(trie_pos[0], s[1] - 'A');
        for (int u = 2, v; u <= n; ++u) {
            scanf("%d", &v);
            G[v].push_back(u);
        }
        trie.dfs(1);    
        sam.init(); trie.bfs(); sam.build();
        int x, len;
        while (q--) {
            scanf("%d%d", &x, &len);
            printf("%d\n", sam.query(trie.t[trie_pos[x]].sam_pos, len));
        }   
    }   
    return 0;
}

M. Kill the tree

题意:
给出一棵有根树,根节点为\(1\),定义\(d(u, v)\)\(u\)\(v\)简单路径的长度,\(c(w) = \sum_{v \in T} d(w, v)\),定义结点\(w\)为一棵树\(T\)的'critical point',当且仅当\(c(w) \leq min_{u \in T} c(u)\)
现在要对于每个\(i \in [1, n]\),要找出以\(i\)为根节点的子树中的'critical point'

思路:
猜想'critical point'就是重心。
问题转化成找重心。
我们考虑假设\(x\)的子树中的所有重心都找出来了:

  • 那么\(x\)子树的重心不可能在它的轻儿子的子树中,因为选\(x\)本身肯定更优
  • 并且\(x\)的重心不可能在它重儿子重心的子树中。
  • 只可能在其重儿子的重心到\(x\)的路径上

暴力判断一下即可,每个点只会被判断一次。
但是这里要求输出所有可能的点,考虑重心最多只有两个,并且是连着的,那么我们找到深度最大的一个,另一个如果存在的话,那么就是它父亲,判一下即可。

代码:


view code

#include <bits/stdc++.h>
using namespace std;
#define dbg(x...) do { cout << "\033[32;1m" << #x << " -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 2e5 + 10;

int n;
vector<vector<int> >G;
int sze[N], fa[N], son[N], res[N];

void dfs(int u, int pre = 0) {
    sze[u] = 1;
    fa[u] = pre;
    for (auto &v : G[u]) {
        if (v == pre) continue;
        dfs(v, u);
        sze[u] += sze[v];
        if (son[u] == -1 || sze[son[u]] < sze[v]) {
            son[u] = v;
        }
    }
    if (son[u] == -1) son[u] = u;
}

void gao(int u) {
    if (sze[u] == 1) {
        res[u] = u;
        return ;
    }
    for (auto &v : G[u]) {
        if (v == fa[u]) continue;
        gao(v);
    }
    int now = res[son[u]];
    while (now != u) {
        int tmp = max(sze[u] - sze[now], sze[son[now]]);
        if (tmp <= sze[u] / 2) {
            break;
        }
        now = fa[now];
    }
//  assert(max(sze[u] - sze[now], sze[son[now]]) <= sze[u] / 2);
    res[u] = now;
}

int main() {
    while (scanf("%d", &n) != EOF) {
        memset(son, -1, sizeof son);
        G.clear();
        G.resize(n + 1);
        for (int i = 1, u, v; i < n; ++i) {
            scanf("%d %d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1);
        gao(1);
        for (int i = 1; i <= n; ++i) {
            vector <int> vec;
            int x = res[i], y = -1;
            vec.push_back(x);
            if (x != i) {
                y = fa[x];
                if (max(sze[i] - sze[y], sze[son[y]]) <= sze[i] / 2) {
                    vec.push_back(y);
                }
            }
            if (vec.size() > 1 && vec[0] > vec[1]) swap(vec[0], vec[1]);
            for (int j = 0, sze = vec.size(); j < sze; ++j)
                printf("%d%c", vec[j], " \n"[j == sze - 1]);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Dup4/p/12005873.html