ACM基础算法与STL模板

0x00 指导思想

下面给出在不同数据范围下,代码的时间复杂度和算法该如何选择:

  1. n ≤ 30 n ≤ 30 n30,指数级别, d f s dfs dfs+剪枝,状态压缩 d p dp dp
  2. n ≤ 100 n ≤ 100 n100 => O ( n 3 ) O\left(n^{3}\right) O(n3) f l o y d floyd floyd d p dp dp,高斯消元
  3. n ≤ 1000 n ≤ 1000 n1000 => O ( n 2 ) O\left(n^{2}\right) O(n2) O ( n 2 log ⁡ n ) O\left(n^{2} \log n\right) O(n2logn) d p dp dp,二分,朴素版 D i j k s t r a Dijkstra Dijkstra、朴素版 P r i m Prim Prim B e l l m a n Bellman Bellman- F o r d Ford Ford
  4. n ≤ 1 e 5 n ≤ 1e5 n1e5 => O ( n ∗ n ) O(n * \sqrt{n}) O(nn ),块状链表、分块、莫队
  5. n ≤ 1 e 6 n ≤ 1e6 n1e6 => O ( n log ⁡ n ) O\left(n \log n\right) O(nlogn)各种 s o r t sort sort,线段树、树状数组、 s e t / m a p set/map set/map h e a p heap heap、拓扑排序、 d i j k s t r a + h e a p dijkstra+heap dijkstra+heap p r i m + h e a p prim+heap prim+heap K r u s k a l Kruskal Kruskal s p f a spfa spfa、求凸包、求半平面交、二分、 C D Q CDQ CDQ分治、整体二分、后缀数组、树链剖分、动态树
  6. n ≤ 1 e 7 n ≤ 1e7 n1e7 => O ( n ) O\left(n \right) O(n), 以及常数较小的 O ( log ⁡ n ) O\left( \log n\right) O(logn)算法,单调队列、 h a s h hash hash、双指针扫描、并查集, k m p kmp kmp A C AC AC自动机,常数比较小的 O ( log ⁡ n ) O\left( \log n\right) O(logn)的做法: s o r t sort sort、树状数组、 h e a p heap heap d i j k s t r a dijkstra dijkstra s p f a spfa spfa
  7. n ≤ 1 e 8 n ≤ 1e8 n1e8 => O ( n ) O\left(n \right) O(n)双指针扫描、 k m p kmp kmp、AC自动机、线性筛素数
  8. n ≤ 1 e 9 n ≤ 1e9 n1e9 => O ( n ) O( \sqrt{n}) O(n ),判断质数
  9. n ≤ 1 e 18 n ≤ 1e18 n1e18 => O ( log ⁡ n ) O\left( \log n\right) O(logn) ,最大公约数,快速幂,数位 D P DP DP
  10. n ≤ 1 e 1000 n ≤ 1e1000 n1e1000 O ( ( log ⁡ n ) 2 ) O\left((\log n)^{2}\right) O((logn)2),高精度加减乘除
  11. n ≤ 1 e 100000 n ≤ 1e100000 n1e100000 O ( log ⁡ k × loglog ⁡ k ) O(\log k \times \operatorname{loglog} k) O(logk×loglogk) k k k表示位数 O ( log ⁡ k × loglog ⁡ k ) O(\log k \times \operatorname{loglog} k) O(logk×loglogk) k k k表示位数 ,高精度加减、 F F T / N T T FFT/NTT FFT/NTT

0x10 基础算法

0x11 归并排序求逆序对

long long m_sort(int q[], int l, int r)
{
    if (l >= r) return 0;

    int mid = l + r >> 1;
    long long res = m_sort(q, l, mid) + m_sort(q, mid + 1, r);

    int i = l, j = mid + 1, k = l;
    while (i <= mid && j <= r) {
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else  {
            // 当q[i] > q[j]时,表明q[i] ~ q[mid]均大于q[j]
            res += mid - i + 1;
            tmp[k ++ ] = q[j ++ ];
        }
    }
    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

    for (i = l, j = l; i <= r; i ++ , j ++ ) q[i] = tmp[j];

    return res;
}

0x12 三分

0x13 前缀和(性质待补)

0x14 差分(性质待补)

0x15 高精度

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

void trans(string a, vector<int> &A)
{
    for (int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
}

bool cmp(string a, string b)
{
    if (a.size() != b.size()) return a.size() > b.size();
    for (int i = 0; i < a.size(); i ++ )
        if (a[i] != b[i])
            return a[i] > b[i];
    return true;
}

string sub(string a, string b);

string add(string a, string b) // 高精度加法
{
    if (a[0] == '-' && b[0] == '-') return '-' + add(a.substr(1), b.substr(1));
    else if (a[0] == '-') return sub(b, a.substr(1));
    else if (b[0] == '-') return sub(a, b.substr(1));

    if (a.size() < b.size()) return add(b, a);

    vector<int> A, B;
    trans(a, A), trans(b, B);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    if (t) C.push_back(t);

    string c = "";
    for (int i = C.size() - 1; i >= 0; i -- ) c += (char)C[i] + '0';
    return c;
}

string sub(string a, string b) // 高精度减法
{
    if (a[0] == '-' && b[0] == '-') return sub(b.substr(1), a.substr(1));
    else if (a[0] == '-') return '-' + add(a.substr(1), b);
    else if (b[0] == '-') return add(a, b.substr(1));

    if (!cmp(a, b)) return '-' + sub(b, a);

    vector<int> A, B;
    trans(a, A), trans(b, B);

    vector<int> C;
    for (int i = 0, t = 0; i < A.size(); i ++ )
    {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0) t = 1;
        else t = 0;
    }
    while (C.size() > 1 && C.back() == 0) C.pop_back();

    string s = "";
    for (int i = C.size() - 1; i >= 0; i -- ) s += (char)C[i] + '0';
    return s;
}

string mul(string a, string b) // 高精乘高精
{
    if (a[0] == '-' && b[0] == '-') return mul(a.substr(1), b.substr(1));
    else if (a[0] == '-') return '-' + mul(a.substr(1), b);
    else if (b[0] == '-') return '-' + mul(a, b.substr(1));

    vector<int> A, B;
    trans(a, A), trans(b, B);

    int num = a.size() + b.size() - 1;
    vector<int> C(num + 1);
    for (int i = 0; i < num; i ++ )
    {
        for (int j = 0; j <= i; j ++ ) 
            C[i] += (j < a.size() ? A[j] : 0) * ((i - j) < b.size() ? B[i - j] : 0);

        if (C[i] >= 0)
        {
            C[i + 1] += C[i] / 10;
            C[i] %= 10;
        }
    }
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    
    string s = "";
    for (int i = C.size() - 1; i >= 0; i -- ) s += (char)C[i] + '0';
    return s;
}

string mul(string a, int b) // 高精度乘法
{
    if (a[0] == '-' && b < 0) return mul(a.substr(1), -b);
    else if (a[0] == '-') return '-' + mul(a.substr(1), b);
    else if (b < 0) return '-' + mul(a, -b);

    vector<int> A;
    trans(a, A);

    vector<int> C;
    int t = 0;
    for(int i = 0; i < A.size() || t; i ++ )
    {
        if(i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }
    while(C.size() > 1 && C.back() == 0) C.pop_back();

    string s = "";
    for (int i = C.size() - 1; i >= 0; i -- ) 
    {
        s += C[i] % 10 + '0';
        C[i] /= 10;
        while (C[i])
        {
            s += (char)(C[i] % 10) + '0';
            C[i] /= 10;
        }
    }
    return s;
}

string div(string a, int b, int &r) // 高精度除法带余数
{
    vector<int> A, C;
    trans(a, A);
    r = 0;
    for(int i = A.size() - 1; i >= 0; i -- )
    {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }
    reverse(C.begin(), C.end());
    while(C.size() > 1 && C.back() == 0) C.pop_back();

    string s = "";
    for (int i = C.size() - 1; i >= 0; i -- ) s += (char)C[i] + '0';
    return s;
}

0x16 合并区间

void merge(vector<PII> &segs)
{
    vector<PII> res;

    sort(segs.begin(), segs.end());

    int st = -2e9, ed = -2e9;
    for (auto seg : segs)
    {
        if (ed < seg.first)
        {
            if (st != -2e9) res.push_back({st, ed});
            st = seg.first, ed = seg.second;
        }
        else ed = max(ed, seg.second);
    }

    if (st != -2e9) res.push_back({st, ed});
    segs = res;
}

0x20 STL

0x21 C++输入输出同步流

ios::sync_with_stdio(0); cin.tie(0); cin.tie(0);

0x22 STL容器

vector, 变长数组,倍增的思想
    size()  返回元素个数
    empty()  返回是否为空
    clear()  清空
    front()/back()
    push_back()/pop_back()
    begin()/end()
    []
    支持比较运算,按字典序

pair<int, int>
    first, 第一个元素
    second, 第二个元素
    支持比较运算,以first为第一关键字,以second为第二关键字(字典序)

string,字符串
    size()/length()  返回字符串长度
    empty()
    clear()
    substr(起始下标,(子串长度))  返回子串
    c_str()  返回字符串所在字符数组的起始地址

queue, 队列
    size()
    empty()
    push()  向队尾插入一个元素
    front()  返回队头元素
    back()  返回队尾元素
    pop()  弹出队头元素

priority_queue, 优先队列,默认是大根堆
    size()
    empty()
    push()  插入一个元素
    top()  返回堆顶元素
    pop()  弹出堆顶元素
    定义成小根堆的方式:priority_queue<int, vector<int>, greater<int>> q;
stack,size()
    empty()
    push()  向栈顶插入一个元素
    top()  返回栈顶元素
    pop()  弹出栈顶元素

deque, 双端队列
    size()
    empty()
    clear()
    front()/back()
    push_back()/pop_back()
    push_front()/pop_front()
    begin()/end()
    []

set, map, multiset, multimap, 基于平衡二叉树(红黑树),动态维护有序序列
    size()
    empty()
    clear()
    begin()/end()
    ++, -- 返回前驱和后继,时间复杂度 O(logn)

    set/multiset
        insert()  插入一个数
        find()  查找一个数
        count()  返回某一个数的个数
        erase()
            (1) 输入是一个数x,删除所有x   O(k + logn)
            (2) 输入一个迭代器,删除这个迭代器
        lower_bound()/upper_bound()
            lower_bound(x)  返回大于等于x的最小的数的迭代器
            upper_bound(x)  返回大于x的最小的数的迭代器
    map/multimap
        insert()  插入的数是一个pair
        erase()  输入的参数是pair或者迭代器
        find()
        []  注意multimap不支持此操作。 时间复杂度是 O(logn)
        lower_bound()/upper_bound()

unordered_set, unordered_map, unordered_multiset, unordered_multimap, 哈希表
    和上面类似,增删改查的时间复杂度是 O(1)
    不支持 lower_bound()/upper_bound(), 迭代器的++--

bitset, 圧位
    bitset<10000> s;

    count()  返回有多少个1

    any()  判断是否至少有一个1
    none()  判断是否全为0

    set()  把所有位置成1
    set(k, v)  将第k位变成v
    reset()  把所有位变成0
    flip()  等价于~
    flip(k) 把第k位取反

0x23 lowbit

int lowbit(int x) // 返回二进制中1的个数
{
    int res = 0;
    for (int i = x; i; i -= i & -i) res ++ ;
    return res;
}

###0x24 去重

// 手动实现(万一有用呢doge)
vector<int>::iterator unique(vector<int> &a)
{
    int j = 0;
    for(int i = 0; i < a.size(); i ++ )
        if(!i || a[i] != a[i - 1])
            a[j ++ ] = a[i];
    // a[0] ~ a[j - 1] 所有a中不重复的数

    return a.begin() + j;
}

sort(alls.begin(), alls.end()); // 排序
alls.erase(unique(alls), alls.end()); // 去重
// alls.erase(unique(alls.begin(), alls.end()), alls.end()); // STLyyds

0x25 常用函数

1. 全排列:next_permutation
//全排列k次就是第k大的数
int a[];
do
{
    for(int i = 0; i < n; i ++) cout << a[i] << ' ';
    cout << '\n';
}
while(next_permutation(a, a + n));

2. 返回容器内最大最小值
min_element(first,last) 寻找范围内最小值,返回迭代器
max_element(first,last)寻找范围内最大值,返回迭代器

vector<int> v = {1, 2, 3};
int maxv = *max_element(v.begin(), v.end());
int minv = *min_element(v.begin(), v.end());
maxv -> 3, minv -> 1;

3. fill(first,last,value)将区间first到last区间全部初始为value

vector<int> v(10);
fill(v.begin(), v.end(), 3);

4. sort类函数

sort (first, last) 对容器或普通数组中 [first, last) 范围内的元素进行排序,默认进行
升序排序。

stable_sort (first, last)sort() 函数功能相似,不同之处在于,对于 [first, last) 
范围内值相同的元素,该函数不会改变它们的相对位置。

partial_sort (first, middle, last)[first,last) 范围内,筛选出 muddle-first 
个最小的元素并排序存放在 [first,middle) 区间中。

eg : vector<int> v = {3, 2, 5, 4, 1, 6, 9, 7};
partial_sort(v.begin(), v.begin() + 4, v.end());
//以默认的升序排序作为排序规则,将 vector 中最小的 4 个元素移动到开头位置并排好序
v -> {1 2 3 4 5 6 9 7}

is_sorted (first, last) 检测 [first, last) 范围内是否已经排好序,默认检测是否按
升序排序。
eg : vector<int> v = {1, 2, 3, 5};
is_sorted(v.begin(), v.end()) == true
5. 进制转换 

stoi(str, 0, 2); //将字符串str从0位置开始到末尾的n进制转换为十进制
string str = "1010";
int a = stoi(str, 0, 2);
cout << a << '\n';
a -> 10

itoa(num, str, 2); //将一个10进制的数转化为n进制的值
int num = 10;
char str[100];
itoa(num, str, 2);
cout << str << '\n';
str -> 1010

C ++ :
cout << "36的8进制:" << std::oct << 36 << endl;
cout << "36的10进制" << std::dec << 36 << endl;
cout << "36的16进制:" << std::hex << 36 << endl;
cout << "36的2进制: " << bitset<8>(36) << endl;


6. reverse

string str = "hello world, hi";
reverse(str.begin(), str.end()); //str结果为 ih ,dlrow olleh
vector<int> v = {5, 4, 3, 2, 1};
reverse(v.begin(), v.end()); //容器v的值变为1, 2, 3, 4, 5

反转从l到r的区间
vector<int> v = {1, 2, 3, 4, 5};
int l = 2, r = 3;
reverse(v.begin() + l, v.begin() + r + 1);
    
v -> {1, 2, 4, 3, 5}

7. 反向迭代器及prev, next

判断字符串回文
string s;
if(s == string(s.rbegin(), s.rend())) cout << "Yes" << '\n';

prev和next
string x(s.rbegin(), s.rend());         //x是s的reverse
string y(s.rbegin(), prev(s.rend()));   //y是x除掉最后一个字母(eg: s == zxy, x = yxz, y = yx)
string z(next(s.rbegin()), s.rend());   //z是s的reverse除掉第一个字母(eg: s == zxy, x = xz)
8. lower_bound()upper_bound()

int a[5] = {1, 2, 3, 4, 5};
//从 a 数组中找到第一个大于等于 3 的元素
int p = lower_bound(a, a + 5, 3) - a;
p -> 2

//从 a 数组中找到第一个大于 3 的元素
int p = upper_bound(a, a + 5, 3) - a;
p -> 3

a[5] = {5, 4, 3, 2, 1};
//从 a 数组中找到第一个小于等于 3 的元素
int p = lower_bound(a, a + 5, 3, greater()) - a;
p -> 2

//从 a 数组中找到第一个小于 3 的元素
int p = upper_bound(a, a + 5, 5, greater()) - a;
p -> 3


9. __builtin函数

__builtin_popcount(x) 返回x的二进制中1的个数
__builtin_ffs (x) 返回x的最后一位1的是从后向前第几位,比如73681110011001000)返回4__builtin_clz (x) 返回前导的0的个数。
__builtin_ctz (x) 返回后面的0个个数,和__builtin_clz相对。
__builtin_parity (x) 返回x的奇偶校验位,也就是x的1的个数模2的结果。

此外,这些函数都有相应的usigned long long版本,只需要在函数名后面加上ll就可以了,
比如int __builtin_clzll。

10. Math函数()
sin()	        返回参数的正弦
sinh()	        返回某个角度的双曲正弦
tan()	        返回参数的切线
tanh()	        返回角度的双曲正切
acos()	        返回反余弦数字
/*
double x = 0.0, result;

result = acos(x);
cout << "acos(x) = " << result << " radians" << endl;

cout << "acos(x) = " << result * 180 / 3.1415 << " degrees" << endl;

acos(x) = 1.5708 radians
acos(x) = 90.0027 degrees
*/

acosh()	        返回数字的双曲余弦值
/*
double x = 13.21, result;
result = acosh(x);

cout << "acosh(x) = " << result << " radian" << endl;
cout << "acosh(x) = " << result * 180 / PI << " degree" << endl;

acosh(x) = 3.27269 radian
acosh(x) = 187.511 degree
*/

asin()	        返回反正弦值
/*
double x = 0.25, result;
result = asin(x);

cout << "asin(x) = " << result << " radians" << endl;
cout << "asin(x) = " << result * 180 / 3.1415 << " degrees" << endl;

asin(x) = 0.25268 radians
asin(x) = 14.4779 degrees
*/


asinh()	        返回数字的双曲正弦值
/*
double x = -6.82, result;

result = asinh(x);
cout << "asinh(x) = " << result << " radian" << endl;
cout << "asinh(x) = " << result * 180 / PI << " degree" << endl;

asinh(x) = -2.61834 radian
asinh(x) = -150.02 degree
*/

atan()	        返回反正切数字
/*
double x = 57.74, result;
result = atan(x);

cout << "atan(x) = " << result << " radians" << endl;

//输出度数
cout << "atan(x) = " << result * 180 / 3.1415 << " degrees" << endl;

atan(x) = 1.55348 radians
atan(x) = 89.0104 degrees
*/

atan2()	        返回坐标的反正切
/*
double x = 10.0, y = -10.0, result;
result = atan2(y, x);

cout << "atan2(y/x) = " << result << " radians" << endl;
cout << "atan2(y/x) = " << result * 180 / 3.141592 << " degrees" << endl;

atan2(y/x) = -0.785398 radians
atan2(y/x) = -45 degrees
*/

atanh()	        返回数字的弧双曲正切
/*
double x = 0.32, result;

result = atanh(x);
cout << "atanh(x) = " << result << " radian" << endl;

cout << "atanh(x) = " << result * 180 / PI << " degree" << endl;

atanh(x) = 0.331647 radian
atanh(x) = 19.002 degree
*/

cbrt()	        计算数字的立方根


copysign(x,y)	它以y的符号返回x的大小。
/*
double x = 34.15, y = -13.0, result;

result = copysign(x, y);
cout << "copysign(" << x << "," << y << ") = " << result << endl;

copysign(34.15,-13) = -34.15
*/

cos()	        返回参数的余弦
/*
double x = 0.5, result;

result = cos(x);
cout << "cos(x) = " << result << endl;

double xDegrees = 25;

//将角度转换为弧度
x = xDegrees * 3.14159 / 180;
result = cos(x);

cout << "cos(x) = " << result << endl;

cos(x) = 0.877583
cos(x) = 0.906308
*/

cosh()	        返回某个角度的双曲余弦值

cosh ⁡ x = e x + e − x 2 \cosh x=\frac{\mathbf{e}^{x}+\mathbf{e}^{-x}}{2} coshx=2ex+ex

/*
double x = 4.55, result;

result = cosh(x);
cout << "cosh(x) = " << result << endl;

double xDegrees = 90;
x = xDegrees * 3.14159 / 180;

result = cosh(x);
cout << "cosh(x) = " << result << endl;

cosh(x) = 47.3215
cosh(x) = 2.50918
*/
exp()	        它计算并返回e的x次幂。
/*
double x = 2.19, result;
result = exp(x);
cout << "exp(x) = " << result << endl;

exp(x) = 8.93521
*/
exp2()	        它计算x的以2为底的指数。
expm1()	        它计算出幂乘以x减一的指数。
/*
double x = 2.19, result;
result = expm1(x);
cout << "e^" << x << " - 1 = " << result << endl;

e^2.19 - 1 = 7.93521
*/

abs()	        返回一个整数的绝对值
fabs()	        返回一个实数的绝对值

fdim(x,y)	返回x和y之间的正差。
/*
若x > y, 返回x - y, 如果x ≤ y 为 0
*/

ceil()	        返回数字的上限值
floor()	        返回十进制数字的下限值

frexp()	        返回一个浮点数的尾数和指数。
/*
double x = 6.81, significand;
int *exp;
significand = frexp(x, exp);
cout << x << " = " << significand << " * 2^" << *exp << endl;

6.81 = 0.85125 * 2^3
*/

ilogb()	        返回|x|的对数的整数部分
/*
int result;
double significand;
double x = 16.81;

result = ilogb(x);
significand = x / pow(FLT_RADIX, result);

cout << "ilogb (" << x << ") = " << result << endl;
cout << x << " = " << significand << " * " << FLT_RADIX << "^" << result << endl << endl;

ilogb (16.81) = 4
16.81 = 1.05062 * 2^4 
*/


fma(x,y,z)	它计算表达式x * y + z。

fmax()	        返回传递的两个参数中最大的
fmin()	        返回两个给定参数中的最小值
fmod()	        计算除法浮点数的余数

ldexp()	        将x和2的乘积返回到幂e
/*
double x = 13.056, result;
int exp = 2;
result = ldexp(x, exp);
cout << "ldexp(x, exp) = " << result << endl;

ldexp(x, exp) = 52.224
*/

llrint()        使用当前舍入模式舍入参数
/*
//默认情况下,舍入方向为最接近的方向,即fesetround(FE_TONEAREST)
double x = 11.87;
long long int result;
result = llrint(x);
cout << "四舍五入到最近 (" << x << ") = " << result << endl;

//中间值四舍五入为更高的整数
x = 11.5;
result = llrint(x);
cout << "四舍五入到最近  (" << x << ") = " << result << endl;

// 将舍入方向设置为DOWNWARD
fesetround(FE_DOWNWARD);
x = 11.87;
result = llrint(x);
cout << "向下舍入 (" << x << ") = " << result << endl;

// 将舍入方向设置为UPWARD
fesetround(FE_UPWARD);
x = 33.32;
result = llrint(x);
cout << "向上舍入 (" << x << ") = " << result << endl;

四舍五入到最近 (11.87) = 12
四舍五入到最近 (11.5) = 12
向下舍入 (11.8699) = 11
向上舍入 (33.3201) = 34
*/

log()	        返回数字的自然对数
log10()	        返回数字的以10为底的对数
log1p()	        返回x + 1的自然对数。
log2(x)	        它计算x的以2为底的对数。
logb(x)	        返回|x|的对数

modf()	        将数字分解为整数和小数部分
/*
double x = 14.86, intPart, fractPart;

fractPart = modf(x, &intPart);
cout << x << " = " << intPart << " + " << fractPart << endl;

x = -31.201;
fractPart = modf(x, &intPart);
cout << x << " = " << intPart << " + " << fractPart << endl;

14.86 = 14 + 0.86
-31.201 = -31 + -0.201
*/

nan()	        返回NaN值
/*
double src = nan("1");
uint64_t dest;

//将变量src复制到dest
//将<cstring>用于memcpy()
memcpy(&dest, &src, sizeof src);
cout << "nan(\"1\") = " << src << " (" << hex << dest << ")\n";

nan("1") = nan (7ff8000000000001)
*/

pow()	        计算幂
sqrt()	        计算数字的平方根
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值