你可能会需要的算法板子(说好的板子,怎么变成cv合集了,恼!

算法模板

不定时更新

C1D-多项式合并:双指针-哈希表

题意:多项式合并:每组数据6行,n /n个系数 /n个次数 /m / m个系数/ m个次数

#include <stdio.h>

//#define abyss
#define MAXN 100005

long long a[MAXN], b[MAXN], A[MAXN], B[MAXN];
long long c[2 * MAXN], C[2 * MAXN];

int main(){
    int tt;  scanf("%d", &tt);
    while(tt--) {
        int n, m;   scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        for(int i = 1; i <= n; i++) scanf("%lld", &A[i]);
        scanf("%d", &m);
        for(int i = 1; i <= m; i++) scanf("%lld", &b[i]);
        for(int i = 1; i <= m; i++) scanf("%lld", &B[i]);

        int topA = 1, topB = 1, cnt = 0;
        while(topA <= n && topB <= m) {
            if(A[topA] == B[topB]) {
                long long tmp = a[topA] + b[topB];
                if(tmp) {c[++cnt] = tmp; C[cnt] = A[topA];}
                topA++; topB++;
            }
            else if(A[topA] < B[topB]) 
                c[++cnt] = a[topA], C[cnt] = A[topA++];
            else 
                c[++cnt] = b[topB], C[cnt] = B[topB++];
        }
        while(topA <= n) {c[++cnt] = a[topA]; C[cnt] = A[topA++];}
        while(topB <= m) {c[++cnt] = b[topB]; C[cnt] = B[topB++];}
        printf("%d\n", cnt);
        for(int i = 1; i <= cnt; i++)   printf("%lld%c", c[i], " \n"[i == cnt]);
        for(int i = 1; i <= cnt; i++)   printf("%lld%c", C[i], " \n"[i == cnt]);
    }
    return 0;
}

C2E-套娃排序:树状数组

题意:每组数据2行,n/n个数字,输出第i个数字在前i个数字里面是第几小

可以直接暴力,树状数组解法

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int tt;
    cin >> tt;
    while (tt--) {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
            int j = i;
            int cnt = 1;
            while (j - 1 >= 0 && a[j] > a[j - 1]) {
                swap(a[j - 1], a[j]);
                j--;
                cnt++;
            }
            cout << cnt << ' ';
        }
        cout << '\n';
    }
    return 0;
}

C1H-逆序对数量:归并排序 OR 树状数组

题意:每组数据两行,n/n个乱序整数,每次可以交换相邻数字,求变成升序交换次数(逆序对数)。题解

//树状数组
#include <bits/stdc++.h>

using namespace std;

class fenwick {
public:
    int n;
    vector<int> arr;
    fenwick(int _n) : n(_n) { arr.resize(n); }
    void modify(int x, int val) {
        while (x < n) {
            arr[x] += val;
            x |= (x + 1);
        }
    }
    int get(int x) {
        int ret = 0;
        while (x >= 0) {
            ret += arr[x];
            x = (x & (x + 1)) - 1;
        }
        return ret;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int tt; cin >> tt;
    while (tt--) {
        int n;
        cin >> n;
        fenwick tr(n + 1);
        long long ans = 0;
        for (int i = 0; i < n; i++) {
            int a;
            cin >> a;
            ans += i - tr.get(a);
            tr.modify(a, 1);
        }
        cout << ans << '\n';
    }
    return 0;
}
//归并排序
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

int n;
int a[N], b[N];

long long merge(int l, int mid, int r) {
    for (int i = l; i <= r; i++) {
        b[i] = a[i];
    }
    int i = l, j = mid + 1, k = l;
    long long cnt = 0;
    while (i <= mid && j <= r) {
        if (b[i] <= b[j]) {
            a[k++] = b[i++];
        } else {
            // b[j] < b[i] => b[j] < b[i], b[i + 1], ... b[mid]
            // so the number is (mid - i + 1)
            a[k++] = b[j++];
            cnt += mid - i + 1;
        }
    }
    while (i <= mid)
        a[k++] = b[i++];
    while (j <= r)
        a[k++] = b[j++];
    return cnt;
}

long long mergeSort(int l, int r) {
    if (l >= r)
        return 0;

    long long cnt = 0;
    int mid = (l + r) / 2;
    cnt += mergeSort(l, mid);
    cnt += mergeSort(mid + 1, r);
    cnt += merge(l, mid, r);
    return cnt;
}

int main() {
//    ios::sync_with_stdio(false);
    cin.tie(0);
    int tt;
    cin >> tt;
    while (tt--) {
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        long long ans = mergeSort(0, n - 1);
        cout << ans << '\n';
    }
    return 0;
}

C1I-淘汰赛:分治法 OR 建树

题意:每组2行数:n / 2 n 2^n 2n个数,两个一组比较,小者淘汰。输出每个数遇到的最大的数。题解

//分治法
#include <bits/stdc++.h>

using namespace std;
int t, n;
int v[1 << 18], ans[1 << 18];

int comp(int l, int r) {
    if (r <= l + 1)
        return l;
    int p1 = comp(l, (l + r) >> 1);
    int p2 = comp((l + r) >> 1, r);
    ans[p1] = max(ans[p1], v[p2]);
    ans[p2] = max(ans[p2], v[p1]);
    if (v[p2] > v[p1])
        return p2;
    return p1;
}

int main() {
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 0; i < (1 << n); i++) {
            cin >> v[i];
            ans[i] = -1;
        }
        comp(0, 1 << n);
        for (int i = 0; i < (1 << n); i++)
            cout << ans[i] << " ";
        cout << endl;
    }
    return 0;
}
//建树,先放个图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

C1J-最大回文数:贪心

题意:每组一个数:n( 1 ≤ n ≤ 1 0 500 1\le n\le 10^{500} 1n10500),输出不超过n的最大回文数。题解

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 505;

char a[N], b[N];
int n, mid;

int leq() {
    for (int i = 1; i <= n; i++) {
        if (b[i] < a[i])
            return 1;
        if (b[i] > a[i])
            return 0;
    }
    return 1;
}

void solve() {
    scanf("%s", a + 1);
    n = strlen(a + 1);
    mid = 1;
    for (int i = 1, j = n; i <= j; i++, j--) {
        b[i] = b[j] = a[i];
        mid = i;
    }
    b[n + 1] = 0;
    if (leq()) {
        printf("%s\n", b + 1);
        return;
    }
    b[mid]--;
    for (int i = mid; i && b[i] < '0'; i--) {
        b[i] += 10;
        b[i - 1]--;
    }
    for (int i = 1; i <= mid; i++)
        b[n - i + 1] = b[i];
    if (b[1] != '0' && leq()) {
        printf("%s\n", b + 1);
        return;
    }
    for (int i = 1; i < n; i++)
        b[i] = '9';
    b[n] = 0;
    printf("%s\n", b + 1);
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}

C2C-随机数生成器:计数排序

题意:每组两行数 :n/n个数 对于一个数组 A = [ a 1 , a 2 , ⋯   , a n ] A = [a_1, a_2, \cdots, a_n] A=[a1,a2,,an] A = [ a 1 , a 2 , ⋯   , a n ] A = [a_1, a_2, \cdots, a_n] A=[a1,a2,,an],定义

f ( A ) = ∑ i = 1 n o r d e r ( a i ) ⋅ a i f(A) = \sum_{i = 1}^n \mathrm{order}(a_i) \cdot a_i f(A)=i=1norder(ai)ai

其中

o r d e r ( a i ) = 1 + ∑ a j < a i 1 ≤ j ≤ n 1 \mathrm{order}(a_i) = 1 + \sum_{\substack{a_j < a_i \\ 1 \leq j \leq n}} 1 order(ai)=1+aj<ai1jn1
例:

一个数 a i a_i ai a i a_i ai o r d e r \mathrm{order} order 定义为 数组内全部元素 比它小的数的个数加一,例如对于 A = [ 1 , 1 , 2 , 3 , 3 , 3 , 4 ] A = [1, 1, 2, 3, 3, 3, 4] A=[1,1,2,3,3,3,4] 有:

o r d e r ( 1 ) = 1 ,   o r d e r ( 2 ) = 3 ,   o r d e r ( 3 ) = 4 ,   o r d e r ( 4 ) = 7 \mathrm{order}(1) = 1, \ \mathrm{order}(2) = 3, \ \mathrm{order}(3) = 4, \ \mathrm{order}(4) = 7 order(1)=1, order(2)=3, order(3)=4, order(4)=7

因此

f ( A ) = 1 ⋅ 1 + 1 ⋅ 1 + 3 ⋅ 2 + 4 ⋅ 3 + 4 ⋅ 3 + 4 ⋅ 3 + 7 ⋅ 4 = 72 f(A) = 1 \cdot 1 + 1 \cdot 1 + 3 \cdot 2 + 4 \cdot 3 + 4 \cdot 3 + 4 \cdot 3 + 7 \cdot 4 = 72 f(A)=11+11+32+43+43+43+74=72

#include <bits/stdc++.h>

using namespace std;

const int N = 100003;

int nextRand() {
    static unsigned int rnd_num = 0x80000001;
    static int mod = 1e5 + 3;

    rnd_num ^= rnd_num >> 10;
    rnd_num ^= rnd_num << 9;
    rnd_num ^= rnd_num >> 25;
    assert(rnd_num != 0);
    return rnd_num % mod;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int tt;
    cin >> tt;
    while (tt--) {
        int n;
        cin >> n;
        vector<int> a(N);
        for (int i = 0; i < n; i++) {
            a[nextRand()]++;
        }
        long long ans = 0;
        int ord = 1;
        for (int i = 0; i < N; i++) {
            ans += (long long) i * ord * a[i];
            ord += a[i];
        }
        cout << ans << '\n';
    }
    return 0;
}

C2D-堆实现C语言

题意:

第一行一个正整数 n n n 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105),表示操作的数量。

接下来 n n n 行,每行为一个操作,格式如下:

  • 1 1 1 x x x:向堆中插入元素 x x x x x x 1 ≤ x ≤ 1 0 9 1 \le x \le 10^9 1x109 1 ≤ x ≤ 1 0 9 1 \le x \le 10^9 1x109)。

  • 2 2 2:删除堆顶元素。

  • 3 3 3:查询堆顶元素。

数据保证后两种操作时堆非空。

输出

对于每次查询堆顶元素时,输出一行一个正整数,表示此时堆顶元素的值。

在所有操作结束后,将堆中的元素从大到小依次输出到一行中。

#include<stdio.h>

#define maxn 1000005
#define inf 0x3f3f3f3f
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)

int n, sz, a[maxn];

void swap(int *a, int *b) {
    int t = *a;
    *a = *b, *b = t;
}

void maxHeapify(int x) {
    int l = ls(x), r = rs(x), larg;
    if (l <= sz && a[l] > a[x]) larg = l;
    else larg = x;
    if (r <= sz && a[r] > a[larg]) larg = r;
    if (larg != x) swap(&a[x], &a[larg]), maxHeapify(larg);
}

void increaseKey(int i, int key) {
    a[i] = key;
    while (i > 1 && a[i / 2] < a[i]) {
        swap(&a[i / 2], &a[i]);
        i = i / 2;
    }
}

void insert(int x) {
    sz += 1;
    a[sz] = -inf;
    increaseKey(sz, x);
}

int top() {
    return a[1];
}

void pop() {
    if (sz < 1) exit(1);
    a[1] = a[sz];
    sz -= 1;
    maxHeapify(1);
}

int main() {
    scanf("%d", &n);
    int i;
    for (i = 1; i <= n; i++) {
        int op, x;
        scanf("%d", &op);
        if (op == 1) {
            scanf("%d", &x);
            insert(x);
        }
        if (op == 2) pop();
        if (op == 3) printf("%d\n", top());
    }
    while (sz) {
        printf("%d ", top()), pop();
    }
}

C2F-多彩数列:滑动窗口

题意:每组数据两行 n k/ n个数,若能把正整数序列变成多彩的,那么输出操作次数,否则输出-1

多彩:如果 A A A 中存在连续 k k k 个数恰好包含 1 , 2 , … , k 1, 2, \dots, k 1,2,,k,则称 A A A 是多彩的。

你可以执行任意次以下操作:

  • 选择不相同的两个下标 i , j i, j i,j 1 ≤ i < j ≤ n 1\leq i < j\leq n 1i<jn),交换 A i A_i Ai A j A_j Aj
#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 1e5 + 5;
int n, k, ans, cnt;
int a[N], tcnt[N], vcnt[N];

void solve() {
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= k; i++)
        tcnt[i] = vcnt[i] = 0;
    cnt = 0;
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        if (!tcnt[a[i]])
            cnt++;
        tcnt[a[i]]++;
    }
    if (cnt != k) {
        printf("-1\n");
        return;
    }
    ans = cnt = 0;
    for (int i = 1; i <= n; i++) {
        if (!vcnt[a[i]])
            cnt++;
        vcnt[a[i]]++;
        if (i > k) {
            vcnt[a[i - k]]--;
            if (!vcnt[a[i - k]])
                cnt--;
        }
        if (cnt > ans)
            ans = cnt;
    }
    ans = k - ans;
    printf("%d\n", ans);
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}

C2H-寻找不共线的点:暴力

题意: 每组数据第一行n<1000,接下来n行,每行x,y,z表示三维坐标,寻找这样一个点A,使得A与所给点集任意两个不共线。存在输出坐标,否则输出-1.题解

暴力破解,枚举m个点,判断所有直线, O ( m n 2 ) O(mn^2) O(mn2)

#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int N = 1005;
int n;
int coord[N][3];
int out[3];

int gcd(int a, int b) {
    if (a == 0 || b == 0)
        return a + b;
    if (a % b == 0)
        return b;
    return gcd(b, a % b);
}

int check() {
    for (int d = 0; d < 3; d++)
        if (out[d] < 1 || out[d] > n)
            return -1;
    for (int i = 1; i <= n; i++) {
        int cnt = 0;
        for (int d = 0; d < 3; d++)
            if (out[d] == coord[i][d])
                cnt++;
        if (cnt == 3)
            return -1;
    }
    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++) {
            int px = coord[j][0] - coord[i][0];
            int py = coord[j][1] - coord[i][1];
            int pz = coord[j][2] - coord[i][2];
            int qx = out[0] - coord[i][0];
            int qy = out[1] - coord[i][1];
            int qz = out[2] - coord[i][2];
            int gp = gcd(gcd(abs(px), abs(py)), abs(pz));
            int gq = gcd(gcd(abs(qx), abs(qy)), abs(qz));
            px /= gp, py /= gp, pz /= gp;
            qx /= gq, qy /= gq, qz /= gq;
            if (px == qx && py == qy && pz == qz)
                return -1;
            if (px == -qx && py == -qy && pz == -qz)
                return -1;
        }
    return 0;
}

int rand(int l, int r) {
    return rand() % (r - l + 1) + l;
}

void solve() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int d = 0; d < 3; d++)
            scanf("%d", &coord[i][d]);
    for (int i = 1; i <= 100; i++) {//枚举点并检查
        for (int d = 0; d < 3; d++)
            out[d] = rand(1, n);
        if (check())
            continue;
        printf("%d %d %d\n", out[0], out[1], out[2]);
        return;
    }
    printf("-1\n");
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}

C2I-矩阵连乘:快速幂

题意:每组数据 第一行-方阵阶数n 接下来n行,表示整数方阵A。输出 A n A^n An

#include <bits/stdc++.h>

#define maxn 205

typedef long long ll;

const int p = 1e9 + 7;

using namespace std;

int n;
ll k;

struct Martix {
    ll a[maxn][maxn];
};

inline Martix multiply(Martix x, Martix y) {
    Martix z;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            z.a[i][j] = 0;
            for (int k = 1; k <= n; k++) {
                z.a[i][j] += x.a[i][k] * y.a[k][j];
                z.a[i][j] %= p;
            }
        }
    }
    return z;
}

inline Martix fpow(Martix x, ll k) {
    Martix y;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == j) y.a[i][j] = 1;
            else y.a[i][j] = 0;
        }
    }
    while (k) {
        if (k & 1) y = multiply(y, x);
        x = multiply(x, x);
        k >>= 1;
    }
    return y;
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d%", &n);
        k = n;
        Martix x;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                scanf("%lld", &x.a[i][j]);
            }
        }
        x = fpow(x, k);
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                printf("%lld ", x.a[i][j]);
            }
            printf("\n");
        }
    }
}

C2J-三叉卡特兰数:递归

C n = ∑ i + j + k = n − 1 i , j , k ≥ 0 C i C j C k C_n = \sum_{\substack{i + j + k = n - 1 \\ i, j, k \geq 0}} C_iC_jC_k Cn=i+j+k=n1i,j,k0CiCjCk

题意: C 0 = 1 C_0=1 C0=1,每组数据一个n,求解第n项

#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 1;
const int mod = 998244353;
long long f[N], s[N];
void init() {
    f[0] = 1;
    s[0] = 1;
    for (int n = 1; n < N; n++) {
        for (int i = 0; i <= n - 1; i++) {
            f[n] += f[i] * s[n - i - 1];
            f[n] %= mod;
        }
        for (int i = 0; i <= n; i++) {
            s[n] += f[i] * f[n - i];
            s[n] %= mod;
        }
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    init();
    int tt;
    cin >> tt;
    while (tt--) {
        int n;
        cin >> n;
        cout << f[n] << '\n';
    }
    return 0;
}

E1C-模拟队列:模拟

题意:第一行n,t表示n个同学,t次操作,初始时每个同学单独一队

接下来 t t t 行,每行为一个操作,格式如下:

  • 1   x   y 1\ x\ y 1 x y: 以学生 y y y 为队首的队伍顺次排在以学生 x x x 为队首的队伍末尾,保证学生 x , y x, y x,y均为所在队伍的队首。

  • 2   x 2\ x 2 x:查询学生 x x x 前方同学的编号,如果学生 x x x 前方没有同学,则输出 0 0 0

  • 3   x 3\ x 3 x:查询学生 x x x 后方同学的编号,如果学生 x x x 后方没有同学,则输出 0 0 0

#include<bits/stdc++.h> 
#define maxn 100005
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
inline int read(){
    int x = 0, f = 1;char ch = getchar();
    while(ch > '9' || ch < '0'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch -'0';ch = getchar();}
    return x * f;
}
int n, T;
int tail[maxn], pre[maxn], nxt[maxn];

void solve(){
    n = read(), T = read();
    for(int i = 1; i <= n; i++) tail[i] = i, pre[i] = nxt[i] = 0;
    while(T--){
       int op;
       scanf("%d", &op);
       if(op == 1){
          int x, y;
          scanf("%d%d", &x, &y);
          pre[y] = tail[x], nxt[tail[x]] = y;
          tail[x] = tail[y];
       }else if(op == 2){
          int x;
          scanf("%d", &x);
          printf("%d\n", pre[x]);
       }else{
          int x;
          scanf("%d", &x);
          printf("%d\n", nxt[x]);
       }
    }
}

int main(){
    int t = read();
    while(t--) {
        solve();
    }
    return 0;
}

E1D-连分数计算:快速幂+费马小定理

题意:

可用一组序列 表示,我们记其第 n n n 项表示为

p n q n = a 0 + 1 a 1 + 1 a 2 + 1 a 3 + 1 ⋱ + 1 a n \frac{p_n}{q_n} = a_0 + \frac{1}{a_1 + \frac{1}{a_2 + \frac{1}{a_3 + \frac{1}{\ddots + \frac{1}{a_n}}}}} qnpn=a0+a1+a2+a3++an11111

现给出 a 0 , a 1 , ⋯   , a n a_0, a_1, \cdots, a_n a0,a1,,an,求出其表示的分数 p n q n \frac{p_n}{q_n} qnpn 在模 998244353 998244353 998244353 意义下的值。即输出 r n = p n ⋅ q n − 1   m o d   998244353 r_n = p_n \cdot q_n^{-1} \bmod 998244353 rn=pnqn1mod998244353,其中 q n − 1 满足 q n ⋅ q n − 1 ≡ 1 ( m o d 998244353 ) q_n^{-1} 满足q_n \cdot q_n^{-1} \equiv 1 \pmod{998244353} qn1满足qnqn11(mod998244353)。测试数据保证 q n q_n qn 的逆元 q n − 1 q_n^{-1} qn1 存在

#include <bits/stdc++.h>

using namespace std;
const int mod = 998244353;

long long fp(long long a, long long x) {
    long long ret = 1;
    while (x) {
        if (x & 1) {
            ret *= a;
            ret %= mod;
        }
        a *= a;
        a %= mod;
        x >>= 1;
    }
    return ret;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int tt;
    cin >> tt;
    while (tt--) {
        int n;
        cin >> n;
        vector<long long> a(n + 1);
        vector<long long> p(n + 1), q(n + 1);
        for (int i = 0; i <= n; i++) 
            cin >> a[i];
        p[0] = a[0];
        q[0] = 1;
        p[1] = (a[0] * a[1] + 1) % mod;
        q[1] = a[1];
        for (int i = 2; i <= n; i++) {
            p[i] = (a[i] * p[i - 1] + p[i - 2]) % mod;
            q[i] = (a[i] * q[i - 1] + q[i - 2]) % mod;
        }
        cout << p[n] * fp(q[n], mod - 2) % mod << '\n';
    }
    return 0;
}

E1G-最多互质数:“待补充”

题意:每组数据两行,第一行n,第二行n个数,在最大公约数不为 1 的前提下,从给定的 n个整数中选择尽可能多的整数,输出选择的整数个数

#include <cstdio>

using namespace std;
const int P = 100;
const int N = 61670;
int p[P], pcnt,n, cnt;
int a[N];
void pre() {
    for (int i = 2; i <= P; i++) {
        int dcnt = 0;
        for (int j = 2; j < i; j++)
            if (i % j == 0)
                dcnt++;
        if (!dcnt)
            p[++pcnt] = i;
    }
}
void solve() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    cnt = 0;
    for (int i = 1; i <= pcnt; i++) {
        int pv = p[i];
        int cur = 0;
        for (int j = 1; j <= n; j++)
            if (a[j] % pv == 0)
                cur++;
        if (cur > cnt)
            cnt = cur;
    }
    printf("%d\n", cnt);
}
int main() {
    pre();
    int T;
    scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}

E1I-掷三个骰子:概率论(可以前缀和优化)

题意:每组数据一行三个数,a,b,c,表示有三个骰子,求随机掷骰子得到三者之和概率最大值

#include <bits/stdc++.h>
using namespace std;
#define MAXN 800
int nums[MAXN];
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int tt;
    cin >> tt;
    while (tt--) {
        int a, b, c;
        cin >> a >> b >> c;
        for (int i = 1; i <= a; i++)
            for (int j = 1; j <= b; j++)
                for (int k = 1; k <= c; k++)
                    nums[i + j + k]++;
        int MAX = 0, res = 0;
        for (int i = 3; i <= a + b + c; i++)
            if (MAX < nums[i])
                MAX = nums[i], res = i;
        cout << res << "\n";
        memset(nums, 0, sizeof(nums));
    }
    return 0;
}

E1J-素点个数:

题意:每组数据一行,每行 4 4 4 个正整数 x 1 , y 1 , x 2 , y 2   ( 1 ≤ x 1 ≤ x 2 ≤ 1 0 6 ,   1 ≤ y 1 ≤ y 2 ≤ 1 0 6 ) x_1, y_1, x_2, y_2 \ (1 \leq x_1 \leq x_2 \leq 10^6, \ 1 \leq y_1 \leq y_2 \leq 10^6) x1,y1,x2,y2 (1x1x2106, 1y1y2106) 表示矩形左下角和右上角的点坐标,输出:矩形范围内满足 x + y , x − y x + y, x - y x+y,xy都为素数的点的个数题解

#include <bits/stdc++.h>

using namespace std;

const int N = 2e6 + 5;
bool vis[N];
int pre[N];
vector<int> primes;

void init() {
    for (int i = 2; i < N; i++) {
        if (!vis[i]) primes.push_back(i);
        for (auto p: primes) {
            if (1LL * i * p >= N) break;
            vis[i * p] = true;
            if (i % p == 0) break;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    init();
    int pos = 1; // skip 2
    for (int i = 1; i < N; i++) {
        pre[i] = pre[i - 1];
        if (i == primes[pos]) {
            pre[i]++;
            pos++;
        }
    }
    int tt;
    cin >> tt;
    while (tt--) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        long long ans = 0;
        int at = 1;
        while (primes[at] < x1 + y1) {
            at++;
        }
        for (; primes[at] <= x2 + y2; at++) {
            int p1 = primes[at];
            int l = max(2 * x1 - p1, p1 - 2 * y2);
            int r = min(2 * x2 - p1, p1 - 2 * y1);
            if (l <= r && 0 <= r) {
                ans += pre[r] - (l - 1 >= 0 ? pre[l - 1] : 0);
            }
        }
        cout << ans << '\n';
    }
    return 0;
}

C3A-钢管切割:动态规划

题意:第一行一个正整数 n n n 1 ≤ n ≤ 1 0 4 1 \le n \le 10^4 1n104),表示钢管的总长度。第二行 n n n 个正整数 p 1 , p 2 , … , p n p_1,p_2,\ldots,p_n p1,p2,,pn 1 ≤ p i ≤ 1 0 7 1 \le p_i \le 10^7 1pi107),表示长度 i i i钢管的价格。

输出:第一行一个正整数,表示最大总销售价格。第二行一个正整数 k k k,表示钢管被分割成 k k k 段。第三行 k k k 个正整数 a 1 , … , a k a_1, \dots, a_k a1,,ak,表示钢管的分割方式,需保证 ∑ a i = n \sum a_i = n ai=n

#include<bits/stdc++.h>
#define maxn 200005
typedef long long ll;
using namespace std;

ll read(){
    ll x = 0, f = 1;char ch = getchar();
    while(ch > '9' || ch < '0'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
int n, p[maxn];
ll f[maxn];
vector<int> ans;

void solve(){
    n = read();
    for(int i = 1; i <= n; i++) p[i] = read();
    for(int i = 1; i <= n; i++){
       for(int j = 0; j < i; j++){
          f[i] = max(f[i], f[j] + p[i - j]);
       }
    }
    printf("%lld\n", f[n]);
    int now = n;
    while(now){
       for(int i = 1; i <= now; i++){
          if(f[now] == f[now - i] + p[i]){
             ans.push_back(i);
             now -= i;
             break;
          }
       }
    }
    printf("%d\n", ans.size());
    for(int i = 0; i < ans.size(); i++) printf("%d%c", ans[i], i == ans.size() - 1 ? '\n' : ' ');
}
int main() {
    int t;
    t = 1;
    while(t--)
        solve();
    return 0;
}

C3C-流水线调度:动态规划

题意:

#include <bits/stdc++.h>

using namespace std;

const long long inf = 1e18;
const int M = 1e5 + 5;

int p[3][M], t[3][3];
long long dp[3][M];

void solve() {
    int m;
    cin >> m;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < m; j++) {
            cin >> p[i][j];
        }
    }
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cin >> t[i][j];
        }
    }
    for (int j = 0; j < m; j++) {
        for (int i = 0; i < 3; i++) {
            dp[i][j] = inf;
            for (int k = 0; k < 3; k++) {
                dp[i][j] = min(
                        dp[i][j],
                        (j - 1 >= 0 ? dp[k][j - 1] + t[k][i] : 0LL) + p[i][j]
                );
            }
        }
    }
    long long ans = inf;
    for (int i = 0; i < 3; i++) {
        ans = min(ans, dp[i][m - 1]);
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int tt;
    cin >> tt;
    while (tt--) solve();
    return 0;
}

C3E-矩阵连乘效率:区间动态规划

题意:第一行一个整数 n n n 2 ≤ n ≤ 300 2 \le n \le 300 2n300) ,表示矩阵的个数。第二行 n + 1 n+1 n+1 个正整数 a 1 , a 2 , … , a n + 1 a_1,a_2,\ldots,a_{n+1} a1,a2,,an+1 1 ≤ a i ≤ 1 0 3 1 \le a_i \le 10^3 1ai103),表示矩阵 A i A_i Ai 的行数和列数为 a i a_i ai a i + 1 a_{i+1} ai+1

输出:一行一个浮点数,表示运算次数最多是最少的多少倍,结果保留4位小数。

#include<bits/stdc++.h>
#define maxn 305
typedef long long ll;
using namespace std;

ll read(){
    ll x = 0, f = 1;char ch = getchar();
    while(ch > '9' || ch < '0'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
int n, a[maxn];
ll f[maxn][maxn];
void solve(){
    n = read();
    memset(f, 0x3f, sizeof(f));
    for(int i = 1; i <= n + 1; i++) a[i] = read(), f[i][i] = 0;
    for(int len = 2; len <= n; len++){
        for(int l = 1; l + len - 1 <= n; l++){
            int r = l + len - 1;
            for(int k = l; k < r; k++){
                f[l][r] = min(f[l][r], f[l][k] + f[k + 1][r] + 1ll * a[l] * a[k + 1] * a[r + 1]);
            }
        }
    }
    ll mx = f[1][n];
    memset(f, 0, sizeof(f));
    for(int len = 2; len <= n; len++){
        for(int l = 1; l + len - 1 <= n; l++){
            int r = l + len - 1;
            for(int k = l; k < r; k++){
                f[l][r] = max(f[l][r], f[l][k] + f[k + 1][r] + 1ll * a[l] * a[k + 1] * a[r + 1]);
            }
        }
    }
    printf("%.4f\n", 1.0 * f[1][n] / mx);
}
int main() {
    int t;
    t = 1;
    while(t--) solve();
    return 0;
}

C3F-导弹轰炸(小偷问题):动态规划

题意:每组测试数据包含两行。第一行包含一个正整数 n ( 2 ≤ n ≤ 1 0 5 ) n(2 \le n \le 10^5) n(2n105)。第二行包含 n n n 个正整数 w 1 , w 2 , … , w n ( 1 ≤ w i ≤ 1 0 5 ) w_1, w_2, \dots, w_n (1 \le w_i \le 10^5) w1,w2,,wn(1wi105),表示每个前哨站的重要程度。数据保证 ∑ n ≤ 4 ⋅ 1 0 5 \sum n \le 4 \cdot10^5 n4105 。不能轰炸连续两个前哨战。

输出:对于每组测试数据,输出一行一个整数,表示在导弹互不干扰的情况下,能够轰炸的前哨站的重要程度之和的最大值。

#include<bits/stdc++.h>
#define maxn 200005
typedef long long ll;
const double eps = 1e-9;
const int mod = 998244353;
using namespace std;

ll read(){
    ll x = 0, f = 1;char ch = getchar();
    while(ch > '9' || ch < '0'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
int n;
ll w[maxn], f[maxn][2];
void solve(){
    n = read();
    for(int i = 1; i <= n; i++) w[i] = read(), f[i][0] = f[i][1] = 0;
    for(int i = 1; i <= n; i++){
       f[i][0] = max(f[i - 1][0], f[i - 1][1]);
       f[i][1] = w[i] + (i == 1 ? 0 : max(f[i - 2][0], f[i - 2][1]));
    }
    printf("%lld\n", max(f[n][0], f[n][1]));
}

int main() {
    int t;
    t = read();
    while(t--) solve();
    return 0;
}

C3H-OBST:区间动态规划

题意:设权值为 i i i 的点深度为 d i d_i di,给定序列 p 1 , p 2 , … , p n p_1,p_2,\ldots,p_n p1,p2,,pn,定义该二叉搜索树的代价和为: ∑ i = 1 n ( d i + 1 ) p i \sum_{i=1}^n(d_i+1)p_i i=1n(di+1)pi。求解集合 { p 1 , p 2 , … , p n } \{p_1,p_2,\ldots,p_n\} {p1,p2,,pn} 所有二叉搜索树中最小的代价和,并输出任意一种最小代价的二叉搜索树结构。

输入:第一行 n,第二行n个正整数 p 1 , p 2 , … , p n p_1,p_2,\ldots,p_n p1,p2,,pn 1 ≤ p i ≤ 1 0 4 1 \le p_i \le 10^4 1pi104

输出:第一行一个正整数,表示最小的代价和。接下共 n n n 行,每行两个整数,分别表示点 i i i 的左儿子节点与右儿子节点,如果点 i i i 无左/右儿子节点,则对应位置输出 − 1 -1 1

#include<bits/stdc++.h>
#define maxn 505
typedef long long ll;
using namespace std;
ll read(){
    ll x = 0, f = 1;char ch = getchar();
    while(ch > '9' || ch < '0'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
int n, m, p[maxn], root;
ll dp[maxn][maxn], sum[maxn];
int rt[maxn][maxn];
int ch[maxn][2];

int dfs(int l, int r){
    if(l > r) return -1;
    int mid = rt[l][r];
    ch[mid][0] = dfs(l, mid - 1);
    ch[mid][1] = dfs(mid + 1, r);
    return mid;
}

void solve(){
    n = read();
    for(int i = 1; i <= n; i++) p[i] = read(), sum[i] = sum[i - 1] + p[i];
    for(int i = 1; i <= n; i++) dp[i][i] = p[i], ch[i][0] = ch[i][1] = -1, rt[i][i] = i;
    for(int len = 2; len <= n; len++){
        for(int l = 1; l + len - 1 <= n; l++){
            int r = l + len - 1;
            dp[l][r] = 1e18;
            for(int k = l; k <= r; k++){
                dp[l][r] = min(dp[l][r], dp[l][k - 1] + dp[k + 1][r] + sum[r] - sum[l - 1]);
            }
            for(int k = l; k <= r; k++){
                if(dp[l][r] == dp[l][k - 1] + dp[k + 1][r] + sum[r] - sum[l - 1]) rt[l][r] = k;
            }
        }
    }
    printf("%lld\n", dp[1][n]);
    dfs(1, n);
    for(int i = 1; i <= n; i++){
        printf("%d %d\n", ch[i][0], ch[i][1]);
    }
}

int main() {
    solve();
    return 0;
}

C3I-查字典:最优二叉搜索树

题意:妮妮会按照以下规则在字典中查找单词:

当妮妮确定自己想要查找的单词在字典的第 l l l 个到第 r r r 个单词之间时,妮妮会查找第 f l , r   ( l ≤ f l , r ≤ r ) f_{l, r} \ (l \leq f_{l, r} \leq r) fl,r (lfl,rr) 个单词,若第 f l , r f_{l, r} fl,r 个单词 s s s 已经是想要查找的单词 t t t,则会停止查字典。若 s s s 的字典序小于 t t t,则妮妮可以确定想要查找的单词 t t t 一定在第 f l , r + 1 f_{l, r} + 1 fl,r+1 到第 个单词之间。同理若 s s s 的字典序大于 t t t,则妮妮可以确定想要查找的单词 t t t 一定在第 l l l 到第 f l , r − 1 f_{l, r} - 1 fl,r1 个单词之间。如此继续查找字典直到查到单词为止。

若字典中共有 m m m 个单词,显然妮妮每次查单词时最开始只能知道想要查找的单词在第 1 1 1 个到第 m m m 个之间,之后妮妮会按照上述规则进行查找,请你确定查找的策略 f l , r f_{l, r} fl,r 使得妮妮在读完这本杂志时,总的查找次数最小。请你求出最小的查找次数

第一行一个正整数 n n n 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1n106)表示单词的个数。第二行 n n n 个单词,保证每个单词长度均为 2 2 2,且均由小写字母组成。保证不同的单词个数不超过 300 300 300 个。

输出一行一个正整数,表示最少的查字典的次数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#include<bits/stdc++.h>
#define maxn 505
typedef long long ll;
const double eps = 1e-9;
const int mod = 998244353;
using namespace std;

ll read(){
    ll x = 0, f = 1;char ch = getchar();
    while(ch > '9' || ch < '0'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}
int n, m, p[maxn], root;
ll dp[maxn][maxn], sum[maxn];
int app[30][30];
int cnt;
char s[5];
void solve(){
    n = read();
    for(int i = 1; i <= n; i++){
        scanf("%s", s + 1);
        app[s[1] - 'a'][s[2] - 'a']++;
    }
    for(int i = 0; i < 26; i++){
        for(int j = 0; j < 26; j++){
            if(app[i][j]) p[++cnt] = app[i][j];
        }
    }
    n = cnt;
    for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + p[i];
    for(int i = 1; i <= n; i++) dp[i][i] = p[i];
    for(int len = 2; len <= n; len++){
        for(int l = 1; l + len - 1 <= n; l++){
            int r = l + len - 1;
            dp[l][r] = 1e18;
            for(int k = l; k <= r; k++){
                dp[l][r] = min(dp[l][r], dp[l][k - 1] + dp[k + 1][r] + sum[r] - sum[l - 1]);
            }
        }
    }
    printf("%lld\n", dp[1][n]);
}

int main() {
    solve();
    return 0;
}

E2D-n元数:递归

一个正整数为 n n n 元数,当且仅当其各位数的 n n n 次方之和等于这个正整数本身。

例如 153 153 153 是一个 3 3 3 3 3 3 元数,因为 1 3 + 5 3 + 3 3 = 153 1^3+5^3+3^3=153 13+53+33=153

给定正整数 n n n,请你求出所有 n n n 元数之和。 n ≤ 12 n\le12 n12

#include <cstdio>
#include <algorithm>
using namespace std;
using ll = long long;
int n;
ll pw[10], cnt[10], bit[10], ans;
int check(ll s) {
    for (int i = 0; i < 10; i++)
        bit[i] = 0;
    while (s) {
        bit[s % 10]++;
        s /= 10;
    }
    for (int i = 0; i < 10; i++)
        if (cnt[i] != bit[i])
            return 0;
    return 1;
}

void dfs(int c, ll s = 0, ll mn = 0, ll b = 1) {
    if (mn > s || c < 0)
        return;
    ans += check(s) * s;
    for (int i = 0; i <= c; i++) {
        cnt[i]++;
        dfs(i, s + pw[i], mn + max(b / 10, b * i), b * 10);
        cnt[i]--;
    }
}

void solve() {
    scanf("%d", &n);
    ans = 0;
    for (int i = 0; i < 10; i++) {
        pw[i] = 1;
        for (int j = 1; j <= n; j++)
            pw[i] *= i;
    }
    dfs(9);
    printf("%lld\n", ans);
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}

E2F-超级计算机:维护优先队列


题目描述

有一台超级计算机,共有 n n n CPU \text{CPU} CPU,这 n n n CPU \text{CPU} CPU 按照 1 ∼ n 1 \sim n 1n 从小到大编号。

该计算机需要完成 m m m 个独立的任务,其会按顺序执行每一个任务。每一个任务会给出三个参数: t , w , s t, w, s t,w,s 。意为在 t t t 时刻将会下达该任务的计算指令,该次任务的权重为 w w w,此时空闲的编号最小的那块 CPU \text{CPU} CPU 将会执行本次计算任务(如果此刻没有空闲的 CPU \text{CPU} CPU 则不会执行该项任务的计算)。该块 CPU \text{CPU} CPU 进入忙碌状态,并在 t + s t + s t+s 时刻计算结束回归空闲状态。

请你计算出在全部执行完这 m m m 个任务后,每一块 CPU \text{CPU} CPU 上共运行了多少权重的任务。

输入

第一个行两个正整数 n n n m m m,表示 CPU \text{CPU} CPU 的数量和任务的个数 ( 1 ≤ n , m ≤ 2 × 1 0 5 1 \le n,m \le 2\times 10^5 1n,m2×105)。

接下来 m m m 行,每行 3 3 3 个整数 t , w , s t, w, s t,w,s(保证当 i < j i < j i<j t i ≤ t j t_i \le t_j titj,其中 0 ≤ t , w , s ≤ 1 0 9 0 \le t,w,s \le 10^9 0t,w,s109)。

输出

输出共 n n n 行,第 i i i 行表示在第 i i i CPU \text{CPU} CPU 上运行任务的权重和。

输入样例

3 5
1 1 3
2 10 100
4 100 10000
10 1000 1000000000
100 1000000000 1
```输出样例

101
10
1000


样例解释

-   在 $t=1$ 时,全部 $\text{CPU}$ 处于空闲状态,因此第一块 $\text{CPU}$ 执行第一个任务,并在 $1 + 3 = 4$ 时刻回归空闲状态。
-   在 $t=2$ 时,第一块 $\text{CPU}$ 在忙碌状态,因此第二块 $\text{CPU}$ 执行第二个任务,并在 $2 + 100 = 102$ 时刻回归空闲状态。
-   在 $t=4$ 时,第一块 $\text{CPU}$ 已回归空闲状态,因此第三个任务由第一块 $\text{CPU}$ 执行。
-   在 $t=10$ 时,此时前两块 $\text{CPU}$ 均在忙碌状态,因此第四个任务由第三块 $\text{CPU}$ 执行。
-   在 $t=100$ 时三块 $CPU$ 均处于忙碌状态,因此第五项任务不执行。
#include<bits/stdc++.h>

using namespace std;

//#define abyss
typedef unsigned int UI;
typedef long long LL;
#define PLL pair<long long, long long>

#define MAXN 200005
priority_queue <PLL, vector<PLL>, greater <PLL> > line,
out;
LL ans[MAXN];

int main() {

    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) line.push({i, 0});
    while (m--) {
        LL T, W, S;
        cin >> T >> W >> S;
        while (!out.empty() && out.top().first <= T) {
            line.push({out.top().second, out.top().first});
            out.pop();
        }
        if (!line.empty()) {
            auto top = line.top();
            line.pop();
            ans[top.first] += W;
            out.push({T + S, top.first});
        }
    }
    for (int i = 1; i <= n; i++) cout << ans[i] << "\n";
    return 0;
}

E2J-右移拿金币:


题目描述

It’s behind you.

在无限长的一维数轴上会出现 n n n 枚金币,第 i i i 枚金币仅在时刻 t i t_i ti 出现在整点 x = x i x=x_i x=xi。你能拿到第 i i i 枚金币,当且仅当你在时刻 t i t_i ti 恰好位于 x = x i x=x_i x=xi

初始时你在 x = 0 x=0 x=0,时刻为 t = 0 t=0 t=0。每个时刻你可以选择保持不动,或是沿坐标轴正方向移动一单位距离。也即如果你在时刻 t t t 位于 x = x 0 x=x_0 x=x0,则时刻 t + 1 t + 1 t+1 你必须位于 x 0 , x 0 + 1 x_0, x_0+1 x0,x0+1 之一。

你最多能拿到多少枚金币呢?

输入

本题测试点包含多组数据。

第一行,一个正整数 T T T 1 ≤ T ≤ 10 1\leq T\leq 10 1T10),表示数据组数。

对于每组数据:

第一行,一个正整数 n n n 1 ≤ n ≤ 2 × 1 0 5 1\leq n\leq 2\times 10^5 1n2×105),表示金币枚数。

接下来 n n n 行,每行两个整数 x i , t i x_i, t_i xi,ti 1 ≤ x i ≤ 1 0 9 1\leq x_i \leq 10^9 1xi109 1 ≤ t i ≤ 1 0 9 1\leq t_i\leq 10^9 1ti109),表示第 i i i 枚金币的位置与出现时间。

输出

对于每组数据:

输出一行,一个整数,表示最多能拿到的金币枚数。

#include <cstdio>
#include <algorithm>
using namespace std;
const int oo = 2e9;
const int N = 2e5 + 5;
int n;
int x[N], t[N];
int p[N], f[N];
int mx;

bool cmp(int a, int b) {
    if (x[a] != x[b])
        return x[a] < x[b];
    return t[a] < t[b];
}

void solve() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &x[i], &t[i]);
        t[i] -= x[i];
        p[i] = i;
        f[i] = oo;
    }
    sort(p + 1, p + n + 1, cmp);
    mx = 0;
    f[0] = 0;
    for (int i = 1; i <= n; i++) {
        int l = 0, r = mx;
        int v = t[p[i]];
        if (v < 0)
            continue;
        while (l < r) {
            int mid = (l + r) / 2 + 1;
            if (v < f[mid])
                r = mid - 1;
            else
                l = mid;
        }
        mx = max(mx, r + 1);
        f[r + 1] = v;
    }
    printf("%d\n", mx);
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--)
        solve();
    return 0;
}

如有版权问题,请联系作者删除/(ㄒoㄒ)/~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值