Codeforces EDU学习之路

EDU学习之路,英语学习之路


Suffix Array

Segment Tree, part 1

Step 1:

Segment Tree for the Sum

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

i64 tree[100010 << 2];
i64 a[100010];
inline void buildtree(int i, int l, i64 r) {
    if (l == r) {
        tree[i] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    tree[i] = tree[i << 1] + tree[i << 1 | 1];
}
inline void update(int i, int l, i64 r, int idx) {
    if (l == r) {
        tree[i] = a[idx];
        return;
    }
    int mid = (l + r) >> 1;
    if (idx <= mid) {
        update(i << 1, l, mid, idx);
    }
    else {
        update(i << 1 | 1, mid + 1, r, idx);
    }
    tree[i] = tree[i << 1] + tree[i << 1 | 1];
}
i64 calc(int i, int l, i64 r, i64 x, i64 y) {
    if (l == x && r == y) {
        return tree[i];
    }
    int mid = (l + r) >> 1;
    if (y <= mid) {
        return calc(i << 1, l, mid, x, y);
    }
    else {
        if (x > mid) {
            return calc(i << 1 | 1, mid + 1, r, x, y);
        }
        else {
            return calc(i << 1, l, mid, x, mid) + calc(i << 1 | 1, mid + 1, r, mid + 1, y);
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    buildtree(1, 1, n);
    while (m--) {
        int sign;
        cin >> sign;
        int l, r;
        cin >> l >> r;
        if (sign == 1) {
            l++;
            a[l] = r;
            update(1, 1, n, l);
        }
        else {
            l++;
            cout << calc(1, 1, n, l, r) << '\n';
        }
    }

    return 0;
}

Segment Tree for the Minimum

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

i64 tree[100010 << 2];
i64 a[100010];
inline void buildtree(int i, int l, int r) {
    if (l == r) {
        tree[i] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    tree[i] = min(tree[i << 1], tree[i << 1 | 1]);
}
inline void update(int i, int l, int r, int idx) {
    if (l == r) {
        tree[i] = a[idx];
        return;
    }
    int mid = (l + r) >> 1;
    if (idx <= mid) {
        update(i << 1, l, mid, idx);
    }
    else {
        update(i << 1 | 1, mid + 1, r, idx);
    }
    tree[i] = min(tree[i << 1], tree[i << 1 | 1]);
}
i64 calc(int i, int l, int r, int x, int y) {
    if (l == x && r == y) {
        return tree[i];
    }
    int mid = (l + r) >> 1;
    if (y <= mid) {
        return calc(i << 1, l, mid, x, y);
    }
    else {
        if (x > mid) {
            return calc(i << 1 | 1, mid + 1, r, x, y);
        }
        else {
            return min(calc(i << 1, l, mid, x, mid), calc(i << 1 | 1, mid + 1, r, mid + 1, y));
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    buildtree(1, 1, n);
    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            int idx;
            i64 v;
            cin >> idx >> v;
            idx++;
            a[idx] = v;
            update(1, 1, n, idx);
        }
        else {
            int l, r;
            cin >> l >> r;
            l++;
            cout << calc(1, 1, n, l, r) << '\n';
        }
    }

    return 0;
}

Number of Minimums on a Segment

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

pair<i64, int> tree[100010 << 2];
i64 a[100010];
inline void buildtree(int i, int l, int r) {
    if (l == r) {
        tree[i].first = a[l];
        tree[i].second = 1;
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    if (tree[i << 1].first > tree[i << 1 | 1].first) {
        tree[i].first = tree[i << 1 | 1].first;
        tree[i].second = tree[i << 1 | 1].second;
    }
    else if (tree[i << 1].first < tree[i << 1 | 1].first) {
        tree[i].first = tree[i << 1].first;
        tree[i].second = tree[i << 1].second;
    }
    else {
        tree[i].first = tree[i << 1].first;
        tree[i].second = tree[i << 1].second + tree[i << 1 | 1].second;
    }
}
inline void update(int i, int l, int r, int idx) {
    if (l == r) {
        tree[i].first = a[idx];
        tree[i].second = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (idx <= mid) {
        update(i << 1, l, mid, idx);
        if (tree[i << 1].first > tree[i << 1 | 1].first) {
            tree[i].first = tree[i << 1 | 1].first;
            tree[i].second = tree[i << 1 | 1].second;
        }
        else if (tree[i << 1].first < tree[i << 1 | 1].first) {
            tree[i].first = tree[i << 1].first;
            tree[i].second = tree[i << 1].second;
        }
        else {
            tree[i].first = tree[i << 1].first;
            tree[i].second = tree[i << 1].second + tree[i << 1 | 1].second;
        }
    }
    else {
        update(i << 1 | 1, mid + 1, r, idx);
        if (tree[i << 1].first > tree[i << 1 | 1].first) {
            tree[i].first = tree[i << 1 | 1].first;
            tree[i].second = tree[i << 1 | 1].second;
        }
        else if (tree[i << 1].first < tree[i << 1 | 1].first) {
            tree[i].first = tree[i << 1].first;
            tree[i].second = tree[i << 1].second;
        }
        else {
            tree[i].first = tree[i << 1].first;
            tree[i].second = tree[i << 1].second + tree[i << 1 | 1].second;
        }
    }
}
pair<i64, int> calc(int i, int l, int r, int x, int y) {
    if (l == x && r == y) {
        return tree[i];
    }
    int mid = (l + r) >> 1;
    if (y <= mid) {
        return calc(i << 1, l, mid, x, y);
    }
    else {
        if (x > mid) {
            return calc(i << 1 | 1, mid + 1, r, x, y);
        }
        else {
            pair<i64, int> ll, rr;
            ll = calc(i << 1, l, mid, x, mid);
            rr = calc(i << 1 | 1, mid + 1, r, mid + 1, y);
            if (ll.first > rr.first) {
                return rr;
            }
            else if (rr.first > ll.first) {
                return ll;
            }
            else {
                pair<i64, int> ans;
                ans.first = ll.first;
                ans.second = ll.second + rr.second;
                return ans;
            }
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    buildtree(1, 1, n);
    while (m--) {
        int op;
        cin >> op;
        pair<i64, int> ans;
        if (op == 1) {
            int idx;
            i64 v;
            cin >> idx >> v;
            idx++;
            a[idx] = v;
            update(1, 1, n, idx);
        }
        else {
            int l, r;
            cin >> l >> r;
            l++;
            ans = calc(1, 1, n, l, r);
            cout << ans.first << " " << ans.second << '\n';
        }
    }

    return 0;
}

Step 2:

Segment with the Maximum Sum

数组要都往大里开,不然会re

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
struct item {
    i64 seg, pref, suf, sum;
};
i64 a[100010 << 2];
item tree[100010 << 2];

inline void buildtree(int i, int l, int r) {
    if (l == r) {
        if (a[l] > 0) {
            tree[i] = {a[l], a[l], a[l], a[l]};
        }
        else {
            tree[i] = {0, 0, 0, a[l]};
        }
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    tree[i] = {max(tree[i << 1].seg, max(tree[i << 1 | 1].seg, tree[i << 1].suf + tree[i << 1 | 1].pref)), 
        max(tree[i << 1].pref, tree[i << 1].sum + tree[i << 1 | 1].pref), 
        max(tree[i << 1 | 1].suf, tree[i << 1 | 1].sum + tree[i << 1].suf), 
        tree[i << 1].sum + tree[i << 1 | 1].sum};
}
inline void update(int i, int l, int r, int idx, int val) {
    if (l == r) {
        if (val > 0) {
            tree[i] = {val, val, val, val};
        }
        else {
            tree[i] = {0, 0, 0, val};
        }
        return;
    }
    int mid = (l + r) >> 1;
    if (idx <= mid) {
        update(i << 1, l, mid, idx, val);
    }
    else {
        update(i << 1 | 1, mid + 1, r, idx, val);
    }
    tree[i] = {max(tree[i << 1].seg, max(tree[i << 1 | 1].seg, tree[i << 1].suf + tree[i << 1 | 1].pref)), 
        max(tree[i << 1].pref, tree[i << 1].sum + tree[i << 1 | 1].pref), 
        max(tree[i << 1 | 1].suf, tree[i << 1 | 1].sum + tree[i << 1].suf), 
        tree[i << 1].sum + tree[i << 1 | 1].sum};
}
item calc(int i, int l, int r, int x, int y) {
    if (x > r || y < l) {
        return {0, 0, 0, 0};
    }
    if (l >= x && r <= y) {
        return tree[i];
    }
    int mid = (l + r) >> 1;
    item s1 = calc(i << 1, l, mid, x, y);
    item s2 = calc(i << 1 | 1, mid + 1, r, x, y);
    return {max(tree[i << 1].seg, max(tree[i << 1 | 1].seg, tree[i << 1].suf + tree[i << 1 | 1].pref)), 
        max(tree[i << 1].pref, tree[i << 1].sum + tree[i << 1 | 1].pref), 
        max(tree[i << 1 | 1].suf, tree[i << 1 | 1].sum + tree[i << 1].suf), 
        tree[i << 1].sum + tree[i << 1 | 1].sum};
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    i64 size = 1;
    while (size < n) {
        size <<= 1;
    }
    buildtree(1, 1, size);
    cout << calc(1, 1, size, 1, n).seg << '\n';
    while (m--) {
        int idx;
        i64 v;
        cin >> idx >> v;
        idx++;
        update(1, 1, size, idx, v);
        cout << calc(1, 1, size, 1, n).seg << '\n';
    }

    return 0;
}

K-th one

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int a[100010];
int tree[100010 << 2];
inline void buildtree(int i, int l, int r) {
    if (l ==r ) {
        tree[i] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    tree[i] = tree[i << 1] + tree[i << 1 | 1];
}
inline void update(int i, int l, int r, int idx) {
    if (l == r) {
        tree[i] = a[idx];
        return;
    }
    int mid = (l + r) >> 1;
    if (idx <= mid) {
        update(i << 1, l, mid, idx);
    }
    else {
        update(i << 1 | 1, mid + 1, r, idx);
    }
    tree[i] = tree[i << 1] + tree[i << 1 | 1];
}
int calc(int i, int l, int r, int k) {
    if (l == r) {
        return l;
    }
    int mid = (l + r) >> 1;
    if (k <= tree[i << 1]) {
        return calc(i << 1, l, mid, k);
    }
    else {
        return calc(i << 1 | 1, mid + 1, r, k - tree[i << 1]);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    buildtree(1, 1, n);
    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            int idx;
            cin >> idx;
            idx++;
            a[idx] = 1 - a[idx];
            update(1, 1, n, idx);
        }
        else {
            int k;
            cin >> k;
            k++;
            cout << calc(1, 1, n, k) - 1 << '\n';
        }
    }

    return 0;
}

First element at least X

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

i64 a[100010];
i64 tree[100010 << 2];

inline void buildtree(int i, int l, int r) {
    if (l == r) {
        tree[i] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    tree[i] = max(tree[i << 1], tree[i << 1 | 1]);
}
inline void update(int i, int l, int r, int idx) {
    if (l == r) {
        tree[i] = a[idx];
        return;
    }
    int mid = (l + r) >> 1;
    if (idx <= mid) {
        update(i << 1, l, mid, idx);

    }
    else {
        update(i << 1 | 1, mid + 1, r, idx);
    }
    tree[i] = max(tree[i << 1], tree[i << 1 | 1]);
}
i64 find(int i, int l, int r, int x) {
    if (l == r) {
        return l;
    }
    int mid = (l + r) >> 1;
    if (x <= tree[i << 1]) {
        return find(i << 1, l, mid, x);
    }
    else if (x <= tree[i << 1 | 1]) {
        return find(i << 1 | 1, mid + 1, r, x);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    buildtree(1, 1, n);
    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            int idx;
            i64 val;
            cin >> idx >> val;
            idx++;
            a[idx] = val;
            update(1, 1, n, idx);
        }
        else {
            i64 x;
            cin >> x;
            int ans = find(1, 1, n, x);
            if (a[ans] < x) {
                ans = -1;
            }
            else {
                ans--;
            }
            cout << ans << '\n';
        }
    }

    return 0;
}

First element at least X - 2

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

i64 a[100010];
i64 tree[100010 << 2];
inline void buildtree(int i, int l, int r) {
    if (l == r) {
        tree[i] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    tree[i] = max(tree[i << 1], tree[i << 1 | 1]);
}
inline void update(int i, int l, int r, int idx) {
    if (l == r) {
        tree[i] = a[idx];
        return;
    }
    int mid = (l + r) >> 1;
    if (idx <= mid) {
        update(i << 1, l, mid, idx);
    }
    else {
        update(i << 1 | 1, mid + 1, r, idx);
    }
    tree[i] = max(tree[i << 1], tree[i << 1 | 1]);
}
i64 find(int i, int l, int r, int x, int idx) {
    if (tree[i] < x) {
        return -1;
    }
    if (r < idx) {
        return -1;
    }
    if (l == r) {
        return l;
    }
    int mid = (l + r) >> 1;
    int res = find(i << 1, l, mid, x, idx);
    if (res == -1) {
        res = find(i << 1 | 1, mid + 1, r, x, idx);
    }
    return res;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    buildtree(1, 1, n);
    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            int idx;
            i64 val;
            cin >> idx >> val;
            idx++;
            a[idx] = val;
            update(1, 1, n, idx);
        }
        else {
            i64 x;
            int idx;
            cin >> x >> idx;
            idx++;
            int ans = find(1, 1, n, x, idx);
            if (ans != -1) {
                ans--;
            }
            cout << ans << '\n';
        }
    }

    return 0;
}

Step 3:

Inversions

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int segtree[100010 << 2];
int a[100010];
int n;
int calc(int i, int l, int r, int x, int y) {
    if (l == x && r == y) {
        return segtree[i];
    }
    int mid = (l + r) >> 1;
    if (y <= mid) {
        return calc(i << 1, l, mid, x, y);
    }
    else {
        if (x > mid) {
            return calc(i << 1 | 1, mid + 1, r, x, y);
        }
        else {
            return calc(i << 1, l, mid, x, mid) + calc(i << 1 | 1, mid + 1, r, mid + 1, y);
        }
    }
}
inline void update(int i, int l, int r, int x) {
    if (l == r) {
        segtree[i] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) {
        update(i << 1, l, mid, x);
    }
    else {
        update(i << 1 | 1, mid + 1, r, x);
    }
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        cout << calc(1, 1, n, a[i], n) << " \n"[i == n - 1];
        update(1, 1, n, a[i]);
    }
    

    return 0;
}

Inversions 2

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int n;
int a[100010];
int segtree[100010 << 2];
inline void buildtree(int i, int l, int r) {
    if (l == r) {
        segtree[i] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
inline void update(int i, int l, int r, int x) {
    if (l == r && l == x) {
        segtree[i] = 0;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) {
        update(i << 1, l, mid, x);
    }
    else {
        update(i << 1 | 1, mid + 1, r, x);
    }
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
int calc(int i, int l, int r, int v) {
    if (l == r) {
        return l;
    }
    int mid = (l + r) >> 1;
    int sum = segtree[i << 1 | 1];
    if (v < sum) {
        return calc(i << 1 | 1, mid + 1, r, v);
    }
    else {
        return calc(i << 1, l, mid, v - sum);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    buildtree(1, 1, n);
    vector<int> ans;
    for (int i = n - 1; i >= 0; i--) {
        int x = calc(1, 1, n, a[i]);
        ans.push_back(x);
        update(1, 1, n, x);
    }
    reverse(ans.begin(), ans.end());
    for (auto it : ans) {
        cout << it << " ";
    }
    puts("");

    return 0;
}

Nested Segments

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int segtree[200010 << 2];
int n;
int a[200010];
int ll[200010], ans[200010];
inline void update(int i, int l, int r, int x) {
    if (l == r) {
        segtree[i] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) {
        update(i << 1, l, mid, x);
    }
    else {
        update(i << 1 | 1, mid + 1, r, x);
    }
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
int calc(int i, int l, int r, int x) {
    if (l == r) {
        return segtree[i];
    }
    int mid = (l + r) >> 1;
    if (x > mid) {
        return calc(i << 1 | 1, mid + 1, r, x);
    }
    return segtree[i << 1 | 1] + calc(i << 1, l, mid, x);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> n;
    n <<= 1;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        if (ll[a[i]]) {
            ans[a[i]] = calc(1, 1, n, ll[a[i]]);
            update(1, 1, n, ll[a[i]]);
        }
        ll[a[i]] = i + 1;
    }
    for (int i = 1; i <= n / 2; i++) {
        cout << ans[i] << " \n"[i == n / 2];
    }

    return 0;
}

Intersecting Segments

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int segtree[200010 << 2];
int n;
int a[200010];
int ll[200010], ans[200010];
inline void update(int i, int l, int r, int x) {
    if (l == r) {
        segtree[i] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) {
        update(i << 1, l, mid, x);
    }
    else {
        update(i << 1 | 1, mid + 1, r, x);
    }
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
int calc(int i, int l, int r, int x) {
    if (l == r) {
        return segtree[i];
    }
    int mid = (l + r) >> 1;
    if (x > mid) {
        return calc(i << 1 | 1, mid + 1, r, x);
    }
    return segtree[i << 1 | 1] + calc(i << 1, l, mid, x);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> n;
    n <<= 1;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        if (ll[a[i]]) {
            int sum = calc(1, 1, n, ll[a[i]]);
            ans[a[i]] = i - ll[a[i]] - sum * 2;
            update(1, 1, n, ll[a[i]]);
        }
        ll[a[i]] = i + 1;
    }
    for (int i = 1; i <= n / 2; i++) {
        cout << ans[i] << " \n"[i == n / 2];
    }

    return 0;
}

Addition to Segment

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

i64 segtree[100010 << 2];
i64 a[100010];
i64 n, m;
inline void update(int i, int l, int r, int x, int y) {
    if (l == r) {
        segtree[i] += y;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) {
        update(i << 1, l, mid, x, y);
    }
    else {
        update(i << 1 | 1, mid + 1, r, x, y);
    }
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
i64 find(int i, int l, int r, int x, int y) {
    if (l > y || r < x) {
        return 0;
    }
    if (l >= x && y >= r) {
        return segtree[i];
    }
    int mid = (l + r) >> 1;
    i64 s1 = find(i << 1, l, mid, x, y);
    i64 s2 = find(i << 1 | 1, mid + 1, r, x, y);
    return s1 + s2;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;
    n += 1;
    while (m--) {
        int op;
        cin >> op;
        if (op == 1) {
            i64 l, r, v;
            cin >> l >> r >> v;
            l++;
            update(1, 1, n, l, v);
            update(1, 1, n, r + 1, -v);
        }
        else {
            i64 x;
            cin >> x;
            x++;
            cout << find(1, 1, n, 1, x) << '\n';

        }
    }

    return 0;
}

Step 4:

Sign alternation

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

i64 segtree[100010 << 2];
i64 a[100010];
i64 n, m;
inline void buildtree(int i, int l, int r) {
    if (l == r) {
        segtree[i] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
inline void update(int i, int l, int r, int x, int y) {
    if (l == r) {
        segtree[i] = y;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) {
        update(i << 1, l, mid, x, y);
    }
    else {
        update(i << 1 | 1, mid + 1, r, x, y);
    }
    segtree[i] = segtree[i << 1] + segtree[i << 1 | 1];
}
i64 calc(int i, int l, int r, int x, int y) {
    if (l == x && r == y) {
        return segtree[i];
    }
    int mid = (l + r) >> 1;
    if (y <= mid) {
        return calc(i << 1, l, mid, x, y);
    }
    else {
        if (x > mid) {
            return calc(i << 1 | 1, mid + 1, r, x, y);
        }
        else {
            return calc(i << 1, l, mid, x, mid) + calc(i << 1 | 1, mid + 1, r, mid + 1, y);
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (i & 1) {
            a[i] = -a[i];
        }
    }
    buildtree(1, 1, n);
    cin >> m;
    while (m--) {
        int op;
        cin >> op;
        if (op == 0) {
            int x;
            i64 v;
            cin >> x >> v;
            if (x % 2 == 1) {
                v = -v;
            }
            update(1, 1, n, x, v);
        }
        else {
            int x, y;
            cin >> x >> y;
            i64 ans = calc(1, 1, n, x, y);
            if (x & 1) {
                ans = -ans;
            }
            cout << ans << '\n';
        }
    }

    return 0;
}

Cryptography

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
i64 mod;
int n, m;
struct node {
    i64 a11, a12, a21, a22;
};
node a[200010], segtree[200010 << 2];
node merge(node x, node y) {
    node ans;
    ans.a11 = (((x.a11 * y.a11) % mod) + ((x.a12 * y.a21) % mod)) % mod;
    ans.a12 = (((x.a11 * y.a12) % mod) + ((x.a12 * y.a22) % mod)) % mod;
    ans.a21 = (((x.a21 * y.a11) % mod) + ((x.a22 * y.a21) % mod)) % mod;
    ans.a22 = (((x.a21 * y.a12) % mod) + ((x.a22 * y.a22) % mod)) % mod;
    return ans;
}
inline void buildtree(int i, int l, int r) {
    if (l == r) {
        segtree[i] = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    buildtree(i << 1, l, mid);
    buildtree(i << 1 | 1, mid + 1, r);
    segtree[i] = merge(segtree[i << 1], segtree[i << 1 | 1]);
}
node calc(int i, int l, int r, int x, int y) {
    if (l == x && r == y) {
        return segtree[i];
    }
    int mid = (l + r) >> 1;
    if (y <= mid) {
        return calc(i << 1, l, mid, x, y);
    }
    else {
        if (x > mid) {
            return calc(i << 1 | 1, mid + 1, r, x, y);
        }
        else {
            node left = calc(i << 1, l, mid, x, mid);
            node right = calc(i << 1 | 1, mid + 1, r, mid + 1, y);
            node res = merge(left, right);
            return res;
        }
    }
}
// node calc(int i, int l, int r, int x, int y) {
//     if (x > r || y < l) {
//         return {1, 0, 0, 1};
//     }
//     if (l >= x && y >= r) {
//         return segtree[i];
//     }
//     int mid = (l + r) >> 1;
//     node left = calc(i << 1, l, mid, x, y);
//     node right = calc(i << 1 | 1, mid + 1, r, x, y);
//     return merge(left, right);
// }
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> mod >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i].a11 >> a[i].a12 >> a[i].a21 >> a[i].a22;
        a[i].a11 %= mod;
        a[i].a12 %= mod;
        a[i].a21 %= mod;
        a[i].a22 %= mod;
    }
    buildtree(1, 1, n);
    while (m--) {
        int l, r;
        cin >> l >> r;
        node ans = calc(1, 1, n, l, r);
        cout << ans.a11 % mod << " " << ans.a12 % mod << '\n' << ans.a21 % mod << " " << ans.a22 % mod << '\n';
        cout << '\n';
    }

    return 0;
}

Number of Inversions on Segment

AC代码:

#include<bits/stdc++.h>
using namespace std;
struct item
{
	long long inv;
	int num[45];
};
struct segtree
{
	int size;
	vector<item> sums;
	item NEUTRAL_ELEMENT;
	void init(int n)
	{
		NEUTRAL_ELEMENT.inv = 0;
		for (int i = 0; i < 45; i++) NEUTRAL_ELEMENT.num[i] = 0;
		size = 1;
		while (size < n) size *= 2;
		sums.assign(2 * size, NEUTRAL_ELEMENT);
	}
	void build(vector<int> &a, int x, int lx, int rx)
	{
		if (rx - lx == 1)
		{
			if (lx < (int)a.size()) sums[x].num[a[lx]]++;
			return ;
		}
		int mid = (lx + rx) / 2;
		build(a, 2 * x + 1, lx, mid);
		build(a, 2 * x + 2, mid, rx);
		sums[x] = merge(sums[2 * x + 1], sums[2 * x + 2]);
	}
	void build(vector<int> &a)
	{
		build(a, 0, 0, size);
	}
	item merge(item a, item b)
	{
		item ans;
		int prev[40];prev[0] = b.num[0];
		ans.inv = a.inv + b.inv;
		for (int i = 0; i < 40; i++)
		{
			ans.num[i] = a.num[i] + b.num[i];
			if (i != 0)
			{
				ans.inv += a.num[i] * prev[i - 1];
				prev[i] = prev[i - 1] + b.num[i];
			}
		}
		return ans;
	}
	void set(int i, int pv, int v, int x, int lx, int rx)
	{
		if (rx - lx == 1)
		{
			sums[x].num[pv]--;
			sums[x].num[v]++;
			return ;
		}
		int mid = (lx + rx) / 2;
		if (i < mid) set(i, pv, v, 2 * x + 1, lx, mid);
		else if (i >= mid) set(i, pv, v, 2 * x + 2, mid, rx);
		sums[x] = merge(sums[2 * x + 1], sums[2 * x + 2]);
	}
	void set(int i, int pv, int v)
	{
		set(i, pv, v, 0, 0, size);	
	}
	item sum(int l, int r, int x, int lx, int rx)
	{
		if (lx >= r || rx <= l) return NEUTRAL_ELEMENT;
		if (lx >= l && rx <= r) return sums[x];
		int mid = (lx + rx) / 2;
		item s1 = sum(l, r, 2 * x + 1, lx, mid);
		item s2 = sum(l, r, 2 * x + 2, mid, rx);
		item s3 = merge(s1, s2);
		return s3;
	}
	item sum(int l, int r)
	{
		return sum(l, r, 0, 0, size);
	}
};
int main()
{
	ios::sync_with_stdio(false);
	int n,m;
	cin >> n >> m;
	segtree st;
	st.init(n);
	vector<int> a(n);
	for (int i = 0; i < n; i++)
	{
		cin>>a[i];
		a[i]--;
	}
	st.build(a);
	while (m--)
	{
		int op;
		cin >> op;
		if (op == 2)
		{
			int i, v;
			cin >> i >> v;
			st.set(i - 1, a[i - 1], v - 1);
			a[i - 1] = v - 1;
		}
		else if (op == 1)
		{
			int l,r;
			cin >> l >> r;
			cout << st.sum(l - 1, r).inv << endl;
		}
	}
}

Number of Different on Segment

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int K = 40+5;
struct segtree
{
	int size;
	vector<long long> sums;
	void init(int n)
	{
		size = 1;
		while (size < n) size *= 2;
		sums.assign(2 * size, 0LL);
	}
	void build(vector<int> &a, int x, int lx, int rx)
	{
		if (rx - lx == 1)
		{
			if (lx < (int)a.size()) sums[x] = a[lx];
			return ;
		}
		int mid = (lx + rx) / 2;
		build(a, 2 * x + 1, lx, mid);
		build(a, 2 * x + 2, mid, rx);
		sums[x] = sums[2 * x + 1] + sums[2 * x + 2];
	}
	void build(vector<int> &a)
	{
		build(a, 0, 0, size);
	}
	void set(int i, int v, int x, int lx, int rx)
	{
		if (rx - lx == 1)
		{
			sums[x] = v;
			return ;
		}
		int mid = (lx + rx) / 2;
		if (i < mid) set(i, v, 2 * x + 1, lx, mid);
		else if (i >= mid) set(i, v, 2 * x + 2, mid, rx);
		sums[x] = sums[2 * x + 1] + sums[2 * x + 2];
	}
	void set(int i, int v)
	{
		set(i, v, 0, 0, size);	
	}
	long long sum(int l, int r, int x, int lx, int rx)
	{
		if (lx >= r || rx <= l) return 0;
		if (lx >= l && rx <= r) return sums[x];
		int mid = (lx + rx) / 2;
		long long s1 = sum(l, r, 2 * x + 1, lx, mid);
		long long s2 = sum(l, r, 2 * x + 2, mid, rx);
		return s1 + s2;
	}
	long long sum(int l, int r)
	{
		return sum(l, r, 0, 0, size);
	}
};
int main()
{
	ios::sync_with_stdio(false);
	int n,m;
	cin >> n >> m;
	segtree st[K];
	vector<int> a(n);
	vector<int> init_array;
	init_array.assign(n, 0);
	for (int i = 0; i < 40; i++)
	{
		st[i].init(n);
		st[i].build(init_array);
	}
	for (int i = 0; i < n; i++)
	{
		cin>>a[i];
		st[a[i] - 1].set(i, 1);
	}
	//st.build(a);
	while (m--)
	{
		int op;
		cin >> op;
		if (op == 1)
		{
			int l, r, ans = 0;
			cin >> l >> r;
			for (int i = 0; i < 40; i++) if (st[i].sum(l - 1, r) > 0) ans++;
			cout << ans << endl;
		}
		else if (op == 2)
		{
			int i, v;
			cin >> i >> v;
			st[a[i - 1] - 1].set(i - 1, 0);
			a[i - 1] = v;
			st[a[i - 1] - 1].set(i - 1, 1);
		}
	}
}

Earthquakes

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const i64 inf = 0x3f3f3f3f3f3f3f3f;
i64 n, m;
i64 segtree[100010 << 2];

inline void update(int i, int l, int r, int x, int y) {
    if (l == r) {
        segtree[i] = y;
        return;
    }
    int mid = (l + r) >> 1;
    if (x <= mid) {
        update(i << 1, l, mid, x, y);
    }
    else {
        update(i << 1 | 1, mid + 1, r, x, y);
    }
    segtree[i] = min(segtree[i << 1], segtree[i << 1 | 1]);
}
i64 calc(int i, int l, int r, int x, int y, int p) {
    if (segtree[i] > p) {
        return 0;
    }
    if (l == r) {
        segtree[i] = inf;
        return 1;
    }
    int mid = (l + r) >> 1;
    i64 res = 0;
    if (x <= mid && segtree[i << 1] <= p) {
        res += calc(i << 1, l, mid, x, y, p);
    }
    if (y > mid && segtree[i << 1 | 1] <= p) {
        res += calc(i << 1 | 1, mid + 1, r, x, y, p);
    }
    segtree[i] = min(segtree[i << 1], segtree[i << 1 | 1]);
    return res;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;
    for (int i = 0; i < (100010 << 2); i++) {
        segtree[i] = inf;
    }
    for (int i = 0; i < m; i++) {
        int op;
        cin >> op;
        if (op == 1) {
            i64 x, y;
            cin >> x >> y;
            x++;
            update(1, 1, n, x, y);
        }
        else {
            int left, right;
            i64 p;
            cin >> left >> right >> p;
            left++;
            cout << calc(1, 1, n, left, right, p) << '\n';
        }
    }

    return 0;
}

​​​​​​Segment Tree, part 2

Binary Search

Step 1:

Binary Search

二分裸题,lower_bound和二分都可

AC代码(lower_bound版):

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    int n, k;
    cin >> n >> k;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    while (k--) {
        int x;
        cin >> x;
        int p = *lower_bound(a.begin(), a.end(), x);
        if (p == x) {
            cout << "YES\n";
        }
        else {
            cout << "NO\n";
        }
    }

    return 0;
}

AC代码(正经二分版):

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    int n, k;
    cin >> n >> k;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    while (k--) {
        int x;
        cin >> x;
        int l = 0, r = n - 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (a[mid] < x) {
                l = mid + 1;
            }
            else {
                r = mid;
            }
        }
        cout << (a[l] == x ? "YES" : "NO") << '\n';
    }

    return 0;
}

Closest to the Left

二分找最大左侧值

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    int n, k;
    cin >> n >> k;
    vector<int> a(n + 2);
    a[0] = 0;
    a[n + 1] = 0x3f3f3f3f;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    while (k--) {
        int x;
        cin >> x;
        int l = 0, r = n + 1;
        while (l + 1 < r) {
            int mid = (l + r) >> 1;
            if (a[mid] <=x) {
                l = mid;
            }
            else {
                r = mid;
            }
        }
        cout << l << '\n';
    }


    return 0;
}

Closest to the Right

二分找右侧最大值

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    int n, k;
    cin >> n >> k;
    vector<int> a(n + 2);
    a[0] = 0;
    a[n + 1] = 0x3f3f3f3f;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    while (k--) {
        int x;
        cin >> x;
        int l = 1, r = n + 1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (a[mid] < x) {
                l = mid + 1;
            }
            else {
                r = mid;
            }
        }
        cout << l << '\n';
    }

    return 0;
}

Fast search

找l到r值域之内有多少个数,直接lower_bound和upper_bound就好了,不要忘了提前排序

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    int n, k;
    cin >> n;
    vector<int> a(n + 2);
    a[0] = -0x3f3f3f3f;
    a[n + 1] = 0x3f3f3f3f;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    sort(a.begin(), a.end());
    cin >> k;
    while (k--) {
        int x, y;
        cin >> x >> y;
        int l, r;
        l = lower_bound(a.begin(), a.end(), x) - a.begin();
        r = upper_bound(a.begin(), a.end(), y) - a.begin();
        cout << r - l << '\n';
    }

    return 0;
}

Step 2:

Packing Rectangles

二分正方形边长

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    i64 w, h, n;
    cin >> w >> h >> n;
    i64 l = 0, r = 1;
    while ((r / w) * (r / h) < n) {
        r <<= 1;
    }
    while (l + 1 < r) {
        i64 mid = (l + r) >> 1;
        if ((mid / w) * (mid / h) >= n) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    cout << r << '\n';

    return 0;
}

Ropes

double类型下的二分,二分绳长,据说while(l + eps < r)容易吃屎,这个题倒是没吃

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);

    int n, k;
    cin >> n >> k;
    vector<double> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    auto check = [&] (double x) {
        int num = 0;
        for (int i = 0; i < n; i++) {
            num += double(a[i] / x);
        }
        return num < k;
    };
    double l = 0, r = 1e9 + 10;
    for (int i = 0; i < 100; i++) {
        double mid = (l + r) / 2;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    cout << setprecision(20) << l << '\n';
    // cout << r << '\n';

    return 0;
}

记:4.17icpc昆明站得知jls的std被卡以后向scanf发起进攻

Very Easy Task

两台打印机,首先就是第一张肯定只能从原本复制过来,所以只用了一台打印机,那么肯定得用用时比较少的那一台,后面就是经典二分时间了,最后不要忘记加上初始第一次打印的时间

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int n, x, y;
bool check(int mid) {
    return mid / x + mid / y >= n;
}

int main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);cout.tie(nullptr);
    
    scanf("%d%d%d", &n, &x, &y);
    n--;
    if (x > y) {
        swap(x, y);
    }
    int l = 0, r = 1;
    while (!check(r)) {
        r <<= 1;
    }
    if (n == 0) {
        r = 0;
    }
    while (l + 1 < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    printf("%d\n", r + x);

    return 0;
}

Children Holiday

依然二分时间,把打球+休息看成是一个区间,同时也要去考虑打完球可能不需要休息就已经达到要求了,这题吃了波大屎,二分完时间忘了用答案去更新ans数组

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int long long
int m, n;
struct node {
    int t, y, z;
}a[1010];
int ans[1010];
bool check(int mid) {
    int sum = 0;
    for (int i = 0; i < n; i++) {
        ans[i] = mid / (a[i].t * a[i].y + a[i].z) * a[i].y;
        ans[i] += min(mid % (a[i].t * a[i].y + a[i].z) / a[i].t, a[i].y);
        sum += ans[i];
    }
    return sum >= m;
}
signed main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);cout.tie(nullptr);
    
    scanf("%lld%lld", &m, &n);
    for (int i = 0; i < n; i++) {
        scanf("%lld%lld%lld", &a[i].t, &a[i].y, &a[i].z);
    }
    int l = 0, r = 1;
    while (!check(r)) {
        r <<= 1;
    }
    if (m == 0) {
        r = 0;
    }
    while (l + 1 < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    printf("%lld", r);
    puts("");
    check(r);
    int tot = 0;
    for (int i = 0; i < n; i++) {
        tot += ans[i];
        if (tot > m) {
            ans[i] -= (tot - m);
            tot = m;
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%lld ", ans[i]);
    }
    puts("");

    return 0;
}
//fd

Equation

二分题意

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;


int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    
    double c;
    cin >> c;
    double l = 0.0, r = 1e5 + 10;
    for (int i = 0; i < 100; i++) {
        double mid = (l + r) / 2;
        if (mid * mid + sqrt(mid) >= c) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    cout << fixed << setprecision(7) << l << '\n';
    
    return 0;
}

String Game

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
string t, p;
int a[200010];
bool check(int mid) {
    string s = t;
    int len = s.size();
    for (int i = 0; i < mid; i++) {
        s[a[i] - 1] = ' ';
    }
    int cnt = 0;
    int len1 = p.size();
    for (int i = 0; i < len; i++) {
        if (s[i] == p[cnt]) {
            cnt++;
            if (cnt == len1) {
                return true;
            }
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    
    cin >> t >> p;
    int lent = t.size();
    int lenp = p.size();
    int l = 0, r = lent;
    for (int i = 0; i < lent; i++) {
        cin >> a[i];
    }
    while (l + 1 < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            l = mid;
        }
        else {
            r = mid;
        }
    }
    cout << l << '\n';
    
    return 0;
}

Student Councils

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int long long
int n, k;
int a[60];
bool check(int mid) {
    int tot = k * mid;
    for (int i = 0; i < n; i++) {
        tot -= min(a[i], mid);
    }
    return tot > 0;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    
    cin >> k >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    int l = 0, r = 1;
    while (!check(r)) {
        r <<= 1;
    }
    while (l + 1 < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    cout << l << '\n';
    
    return 0;
}

Hamburgers

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
string s;
i64 len, nb, ns, nc, pb, ps, pc;
i64 r1;
i64 cnt1, cnt2, cnt3;
bool check(i64 mid) {
    i64 x = max(mid * cnt1 - nb, 0ll), y = max(mid * cnt2 - ns, 0ll), z = max(mid * cnt3 - nc, 0ll);
    return r1 - x * pb - y * ps - z * pc < 0;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);cout.tie(nullptr);
    
    cin >> s;
    len = s.size();
    cin >> nb >> ns >> nc;
    cin >> pb >> ps >> pc;
    cin >> r1;
    for (int i = 0; i < len; i++) {
        if (s[i] == 'B') {
            cnt1++;
        }
        else if (s[i] == 'S') {
            cnt2++;
        }
        else {
            cnt3++;
        }
    }
    i64 l = 0, r = 1;
    while (!check(r)) {
        r <<= 1;
    }
    // cout << r << '\n';
    while (l + 1 < r) {
        i64 mid = (l + r) >> 1;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    cout << l << '\n';
    // cout << r << '\n';

    return 0;
}

Get together

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

pair<double, double> a[100010];
int n;
bool check(double mid) {
    double left = -DBL_MAX, r = DBL_MAX;
    for (int i = 0; i < n; i++) {
        double i_left = a[i].first - a[i].second * mid, i_right = a[i].first + a[i].second * mid;
        if (i_left > r || i_right < left) {
            return false;
        }
        left = max(left, i_left);
        r = min(i_right, r);
    }
    return true;
}
int main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);

    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%lf%lf", &a[i].first, &a[i].second);
    }
    double l = 0, r = 1;
    while (!check(r)) {
        r *= 2;
    }
    for (int i = 0; i < 200; i++) {
        double mid = (l + r) / 2;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    cout << fixed << setprecision(6) << l << '\n';

    return 0;
}

Splitting an Array

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int n, k;
int a[100010];

bool check(i64 mid) {
    i64 sum = 0;
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] > mid) {
            return false;
        }
        else {
            cnt++;
            int j = i;
            while (j < n && sum + a[j] <= mid) {
                sum += a[j];
                j++;
            }
            i = j - 1;
            sum = 0;
        }
    }
    return cnt <= k;
}

int main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);

    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    i64 l = 0, r = 1;
    while (!check(r)) {
        r <<= 1;
    }
    while (l + 1 < r) {
        i64 mid = (l + r) >> 1;
        if (check(mid)) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    printf("%lld\n", r);


    return 0;
}

Cows in Stalls

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int n, k;
int a[10010];
bool check(int mid) {
    int cnt = 1;
    int pre = a[1];
    for (int i = 2; i <= n; i++) {
        if (a[i] - pre >= mid) {
            cnt++;
            pre = a[i];
        }
    }
    return cnt >= k;
}
int main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);

    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }
    int l = 0, r = 1;
    while (check(r)) {
        r <<= 1;
    }
    while (l + 1 < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            l = mid;
        }
        else {
            r = mid;
        }
    }
    printf("%d\n", l);

    return 0;
}

Disjoint Sets Union

Disjoint Sets Union

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

int fa[100010];
int getfa(int x) {
    return x == fa[x] ? fa[x] : fa[x] = getfa(fa[x]);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        fa[i] = i;
    }
    for (int i = 0; i < m; i++) {
        string s;
        cin >> s;
        int x, y;
        cin >> x >> y;
        if (s[0] == 'u') {
            int fx = getfa(x), fy = getfa(y);
                if (fx != fy) {
                    fa[fx] = fy;
                }
        }
        else {
            if (getfa(x) != getfa(y)) {
                cout << "NO\n";
            }
            else {
                cout << "YES\n";
            }
        }
    }

    return 0;
}

Disjoint Sets Union 2

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

struct node {
    int p, r, num, maxx, minn;
}fa[300010];


void merge(int x, int y) {
    fa[y].p = x;
    fa[x].maxx = max(fa[y].maxx, fa[x].maxx);
    fa[x].minn = min(fa[y].minn, fa[x].minn);
    fa[x].num = fa[y].num + fa[x].num;
}

int getfa(int x) {
    int y;
    return x == fa[x].p ? x : getfa(fa[x].p);
}
void __union(int x, int y) {
    int xx = getfa(x);
    int yy = getfa(y);
    if (xx == yy) {
        return;
    }
    if (fa[xx].r == fa[yy].r) {
        fa[xx].r++;
    }
    if (fa[xx].r > fa[yy].r) {
        merge(xx, yy);
    }
    else {
        merge(yy, xx);
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <=n ; i++) {
        fa[i].p = i;
        fa[i].r = 0;
        fa[i].num = 1;
        fa[i].maxx = i;
        fa[i].minn = i;
    }
    for (int i = 0; i < m; i++) {
        string s;
        cin >> s;
        if (s[0] == 'u') {
            int x, y;
            cin >> x >> y;
            __union(x, y);
        }
        else {
            int x, y;
            cin >> x;
            y = getfa(x);
            cout << fa[y].minn << " " << fa[y].maxx << " " << fa[y].num << '\n';
        }
    }

    return 0;
}

Experience

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

struct node {
    int p, r, add, pre;
}fa[200010];

void merge(int x, int y) {
    fa[y].p = x;
    fa[y].pre = fa[x].add;
}

int getfa(int x) {
    return x == fa[x].p ? x : getfa(fa[x].p);
}
int sum(int x) {
    int y = getfa(x);
    if (x == y) {
        return fa[y].add;
    }
    else {
        return fa[x].add - fa[x].pre + sum(fa[x].p);
    }
}
void _union(int x, int y) {
    x = getfa(x);
    y = getfa(y);
    if (x == y) {
        return;
    }
    if (fa[x].r == fa[y].r) {
        fa[x].r++;
    }
    if (fa[x].r > fa[y].r) {
        merge(x, y);
    }
    else {
        merge(y, x);
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        fa[i].p = i;
        fa[i].r = 0;
        fa[i].pre = 0;
        fa[i].add = 0;
    }
    for (int i = 0; i < m; i++) {
        string s;
        cin >> s;
        if (s[0] == 'j') {
            int x, y;
            cin >> x >> y;
            _union(x, y);
        }
        else if (s[0] == 'a') {
            int x, y;
            cin >> x >> y;
            x = getfa(x);
            fa[x].add += y;
        }
        else {
            int x;
            cin >> x;
            cout << sum(x) << '\n';
        }
    }

    return 0;
}

Two Pointers Method

Step 1:

Merging Arrays

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int n, m;
int a[100010], b[100010], c[200010];

int main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);cout.tie(nullptr);
    
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n + m; i++) {
        scanf("%d", &c[i]);
    }
    sort(c, c + n + m);
    for (int i = 0; i < n + m; i++) {
        printf("%d%c", c[i], i == n + m - 1 ? '\n' : ' ');
    }

    return 0;
}

Number of Smaller

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int n, m;
int a[100010], b[100010];

int main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);cout.tie(nullptr);
    
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < m; i++) {
        scanf("%d", &b[i]);
    }
    int i = 0, j = 0;
    while (i < n && j < m) {
        if (a[i] >= b[j]) {
            b[j] = i;
            j++;
        }
        else {
            i++;
        }
    }
    if (j != m) {
        for (int x = j; x < m; x++) {
            b[x] = i;
        }
    }
    for (int i = 0; i < m; i++) {
        printf("%d%c", b[i], i == m - 1 ? '\n' : ' ');
    }

    return 0;
}

Number of Equal

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int long long
int n, m;
int a[100010], b[100010];
int cnt1[100010], cnt2[100010];

signed main() {
    // ios::sync_with_stdio(false);
    // cin.tie(nullptr);cout.tie(nullptr);
    
    scanf("%lld%lld", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%lld", a + i);
        cnt1[i] = 1;
        if (i >= 1 && a[i] == a[i - 1]) {
            cnt1[i - 1]++;
            i--;
            n--;
        }
    }
    for (int i = 0; i < m; i++) {
        scanf("%lld", b + i);
        cnt2[i] = 1;
        if (i >= 1 && b[i] == b[i - 1]) {
            cnt2[i - 1]++;
            i--;
            m--;
        }
    }
    int i = 0, j = 0;
    int ans = 0;
    while (i < n && j < m) {
        if (a[i] > b[j]) {
            j++;
        }
        else if (a[i] < b[j]) {
            i++;
        }
        else {
            ans += cnt1[i] * cnt2[j];
            i++;
            j++;
        }
    }
    printf("%lld\n", ans);

    return 0;
}

Step 2:

Segment with Small Sum

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, s;
    cin >> n >> s;
    vector<i64> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    i64 ans = 0;
    i64 sum = 0;
    int l = 0, r = 0;
    while (l < n && r < n) {
        if (sum + a[r] <= s) {
            sum += a[r];
            ans = max(ans, 1ll * r - l + 1);
            r++;
        }
        else {
            sum -= a[l];
            l++;
        }
    }
    cout << ans << '\n';

    return 0;
}

Segment with Big Sum

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, s;
    cin >> n >> s;
    vector<i64> a(n);
    i64 cnt = 0;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        cnt += a[i];
    }
    if (cnt < s) {
        cout << "-1\n";
        exit(0);
    }
    i64 ans = n + 1;
    int l = 0;
    i64 sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
        while (sum - a[l] >= s && l < n) {
            sum -= a[l];
            l++;
        }
        if (sum >= s) {
            ans = min(ans, 1ll * i - l + 1);
        }
    }
    cout << ans << '\n';

    return 0;
}

Number of Segments with Small Sum

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, s;
    cin >> n >> s;
    vector<i64> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    i64 ans = 0;
    i64 res = 0;
    i64 sum = 0;
    int l = 0, r = 0;
    while (l < n && r < n) {
        if (sum + a[r] <= s) {
            sum += a[r];
            res += r - l + 1;
            r++;
        }
        else {
            sum -= a[l];
            l++;
        }
    }
    cout << res << '\n';

    return 0;
}

Number of Segments with Big Sum

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, s;
    cin >> n >> s;
    vector<i64> a(n);
    i64 cnt = 0;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        cnt += a[i];
    }
    i64 res = 0;
    int l = 0;
    i64 sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
        while (sum - a[l] >= s && l < n) {
            sum -= a[l];
            l++;
        }
        if (sum >= s) {
            res += l + 1;
        }
    }
    cout << res << '\n';

    return 0;
}

Segments with Small Set

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, k;
    cin >> n >> k;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    if (k == 0) {
        cout << "0\n";
        exit(0);
    }
    i64 sum = 0, l = 0;
    i64 ans = 0;
    map<i64, int> mp;
    for (int i = 0; i < n; i++) {
        mp[a[i]]++;
        if (mp[a[i]] == 1) {
            sum++;
        }
        while (sum > k) {
            mp[a[l]]--;
            if (mp[a[l]] == 0) {
                sum--;
            }
            l++;
        }
        ans += i - l + 1;
    }
    cout << ans << '\n';

    return 0;
}

Segments with Small Spread

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n, k;
    cin >> n >> k;
    vector<i64> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    multiset<i64> ms;
    i64 l = 0, ans = 0;
    for (int i = 0; i < n; i++) {
        ms.insert(a[i]);
        while (*ms.rbegin() - *ms.begin() > k) {
            ms.erase(ms.find(a[l++]));
        }
        ans += i - l + 1;
    }
    cout << ans << '\n';

    return 0;
}

Coprime Segment

st1存储删除元素,st2存储添加元素,val1数组来存储st1内含有元素的gcd,val2数组来存储st2内含有元素的gcd

解析传送门

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

i64 gcd(i64 x, i64 y) {
    return y == 0 ? x : gcd(y, x % y);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    i64 n;
    cin >> n;
    vector<i64> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    stack<i64> st1, st2;
    vector<i64> val1 = { 0 }, val2 = { 0 };
    int l = 0;
    i64 ans = 1e9;
    for (int i = 0; i < n; i++) {
        st2.push(a[i]);
        val2.push_back(gcd(val2.back(), a[i]));
        while (gcd(val1.back(), val2.back()) == 1) {
            ans = min(ans, 1ll * i - l + 1);
            if (st1.empty()) {
                while (!st2.empty()) {
                    st1.push(st2.top());
                    val1.push_back(gcd(val1.back(), st2.top()));
                    st2.pop();
                    val2.pop_back();
                }
            }
            st1.pop();
            val1.pop_back();
            l++;
        }
    }
    if (ans == 1e9) {
        cout << "-1\n";
    }
    else {
        cout << ans << '\n';
    }

    return 0;
}

Step 3:

Looped Playlist

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    i64 p;
    cin >> n >> p;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    i64 sum = accumulate(a.begin(), a.end(), 0ll);
    a.insert(a.end(), a.begin(), a.end());
    i64 ans = 9e18;
    int now = -1;
    i64 base = p / sum * n;
    i64 current = p / sum * sum;
    for (int i = 0, j = 0; i < n; i++) {
        while (current < p) {
            current += a[j++];
        }
        if (base + j - i < ans) {
            ans = base + j - i;
            now = i;
        }
        current -= a[i];
    }
    cout << now + 1 << " " << ans << '\n';
    
    return 0;
}

Courses - Codeforces

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    i64 s;
    cin >> n >> s;
    vector<int> a(n);
    for (int &x : a) {
        cin >> x;
    }
    i64 ans = 0;
    i64 sum = 0;
    for (int i = 0, j = 0; i < n; i++) {
        while (j < n && sum + a[j] <= s) {
            sum += a[j++];
        }
        ans += 1ll * (j - i) * (j - i + 1) / 2;
        sum -= a[i];
    }
    cout << ans << '\n';
    
    return 0;
}

Che city

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define int long long


signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, r;
    cin >> n >> r;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    for (int i = n - 1; i >= 1; i--) {
        a[i] -= a[i - 1];
    }
    int sum = 0, l = 1;
    int ans = 0;
    for (int i = 1; i < n; i++) {
        sum += a[i];
        while (sum - a[l] > r) {
            sum -= a[l++];
        }
        if (sum > r) {
            ans += l;
        }
    }
    cout << ans << '\n';
    
    return 0;
}

Stylish clothes

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

struct node {
    int val, c;
}a[400010];
queue<int> qu[4];
int ans[4];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n = 0;
    for (int i = 0; i < 4; i++) {
        int x;
        cin >> x;
        for (int j = 0; j < x; j++) {
            int y;
            cin >> y;
            a[n++] = {y, i};
        }
    }
    sort(a, a + n, [&](node a, node b) {
        return a.val < b.val;
    });
    int maxx = 1e9;
    int sum = 0, l = 0;
    for (int i = 0; i < n; i++) {
        qu[a[i].c].push(a[i].val);
        if (qu[a[i].c].size() == 1) {
            sum++;
        }
        while (sum == 4) {
            if (a[i].val - a[l].val < maxx) {
                maxx = a[i].val - a[l].val;
                for (int j = 0; j < 4; j++) {
                    ans[j] = qu[j].front();
                }
                ans[a[i].c] = a[i].val;
            }
            qu[a[l].c].pop();
            if (qu[a[l].c].empty()) {
                sum--;
            }
            l++;
        }
    }
    for (int i = 0; i < 4; i++) {
        cout << ans[i] << " \n"[i == 3];
    }
    
    return 0;
}

Knapsack on a Segment

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    i64 s;
    cin >> n >> s;
    vector<pair<i64, i64>> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i].first;
    }
    for (int i = 0; i < n; i++) {
        cin >> a[i].second;
    }
    i64 sum = 0, ans = 0, cnt = 0;
    for (int i = 0, j = 0; i < n; i++) {
        while (j < n && sum + a[j].first <= s) {
            sum += a[j].first;
            cnt += a[j].second;
            ans = max(ans, cnt);
            j++;
        }
        sum -= a[i].first;
        cnt -= a[i].second;
    }
    cout << ans << '\n';
    
    return 0;
}

Card Substrings

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    string s, a;
    cin >> s;
    cin >> a;
    map<char, int> mp;
    for (int i = 0; i < m; i++) {
        mp[a[i]]++;
    }
    map<char, int> cnt;
    i64 ans = 0;
    int flag = 0;
    for (int i = 0, j = 0; i < n; i++) {
        cnt[s[i]]++;
        if (cnt[s[i]] == mp[s[i]] + 1) {
            flag++;
        }
        while (flag) {
            cnt[s[j]]--;
            if (cnt[s[j]] == mp[s[j]]) {
                flag--;
            }
            j++;
        }
        if (!flag) {
            ans += i - j + 1;
        }
    }
    cout << ans << '\n';
    
    return 0;
}

Not Very Rude Substring

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    i64 c;
    cin >> n >> c;
    string s;
    cin >> s;
    i64 ans = 0, sum = 0;
    map<char, int> mp;
    for (int i = 0, j = 0; i < n; i++) {
        if (s[i] == 'b') {
            sum += mp['a'];
        }
        mp[s[i]]++;
        while (sum > c) {
            if (s[j] == 'a') {
                sum -= mp['b'];
            }
            mp[s[j]]--;
            j++;
        }
        ans = max(ans, 1ll * i - j + 1);
    }
    cout << ans << '\n';
    
    return 0;
}

A-B Knapsack

AC代码:

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;



int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    i64 s, A, B;
    cin >> n >> m >> s >> A >> B;
    vector<i64> a(n + 1), b(m + 1);
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= m; i++) {
        cin >> b[i];
    }
    sort(a.begin() + 1, a.end(), [&](i64 a, i64 b) {
        return a > b;
    });
    sort(b.begin() + 1, b.end(), [&](i64 a, i64 b) {
        return a > b;
    });
    for (int i = 1; i <= n; i++) {
        a[i] += a[i - 1];
    }
    for (int i = 1; i <= m; i++) {
        b[i] += b[i - 1];
    }
    i64 ans = 0;
    for (int i = 0, j = m; i <= n; i++) {
        if (A * i > s) {
            break;
        }
        while (A * i + B * j > s && j >= 0) {
            j--;
        }
        ans = max(ans, a[i] + b[j]);
    }
    cout << ans << '\n';
    
    return 0;
}

Segment with the Required Subset

jiangly's代码:(因为我不太会

#include <bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n, s;
    std::cin >> n >> s;
    std::vector<int> a(n);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    }
    int ans = n + 1;
    std::vector<std::bitset<1001>> L(1), R(1);
    L[0][0] = R[0][s] = 1;
    for (int i = 0, j = 0; i < n; i++) {
        while (j <= n && !(L.back() & R.back()).any()) {
            if (j < n) {
                R.push_back(R.back() | R.back() >> a[j]);
            }
            j++;
        }
        if (j > n) {
            break;
        }
        ans = std::min(ans, j - i);
        if (L.size() == 1) {
            assert(R.size() > 1);
            for (int k = j - 1; k > i; k--) {
                L.push_back(L.back() | L.back() << a[k]);
            }
            R.resize(1);
        } else {
            L.pop_back();
        }
    }
    if (ans > n) {
        ans = -1;
    }
    std::cout << ans << "\n";
    return 0;
}

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值