Commonly used code template 1 from Peking University NOIP gold medalist yxc-basic algorithm

1. Quick sort algorithm template

void quick_sort(int q[], int l, int r)
{
    
    
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
    
    
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

2. Merge sort algorithm template

void merge_sort(int q[], int l, int r)
{
    
    
    if (l >= r) return;
    int mid = l + r >> 1;
    merge_sort(q, l, mid);
    merge_sort(q, mid + 1, r);

    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
        else tmp[k ++ ] = q[j ++ ];

    while (i <= mid) tmp[k ++ ] = q[i ++ ];
    while (j <= r) tmp[k ++ ] = q[j ++ ];

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

3. Integer dichotomy algorithm template

bool check(int x) {
    
    /* ... */} // 检查x是否满足某种性质

// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
    
    
    while (l < r)
    {
    
    
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断mid是否满足性质
        else l = mid + 1;
    }
    return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_2(int l, int r)
{
    
    
    while (l < r)
    {
    
    
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

4. Floating point dichotomy algorithm template

bool check(double x) {
    
    /* ... */} // 检查x是否满足某种性质

double bsearch_3(double l, double r)
{
    
    
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
    
    
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

5. High precision addition

// C = A + B, A >= 0, B >= 0
vector<int> add(vector<int> &A, vector<int> &B)
{
    
    
    if (A.size() < B.size()) return add(B, A);

    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);
    return C;
}

6. High precision subtraction

// C = A - B, 满足A >= B, A >= 0, B >= 0
vector<int> sub(vector<int> &A, vector<int> &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();
    return C;
}

7. High precision multiplied by low precision

// C = A * b, A >= 0, b > 0
vector<int> mul(vector<int> &A, int b)
{
    
    
    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();

    return C;
}

8. High precision divided by low precision

// A / b = C ... r, A >= 0, b > 0
vector<int> div(vector<int> &A, int b, int &r)
{
    
    
    vector<int> C;
    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();
    return C;
}

9. One-dimensional prefix sum

S[i] = a[1] + a[2] + ... a[i]
a[l] + ... + a[r] = S[r] - S[l - 1]

10. Two-dimensional prefix sum

S[i, j] =The first iline of jthe grid and the upper left part of all elements
to (x1, y1)the upper left corner, (x2, y2)for the child and for the lower right corner of the matrix:
S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]

11. One-dimensional difference

Interval to [l, r]each number in plus c: B[l] += c,B[r + 1] -= c

12. Two-dimensional difference

Give (x1, y1)the upper left corner, (x2, y2)plus c for all elements in the lower right corner of the sub-matrix:
S[x1, y1] += c, S[x2 + 1, y1] -= c, S[x1, y2 + 1] -= c,S[x2 + 1, y2 + 1] += c

13.Bit operations

Seeking nthe first kdigit: n >> k & 1
Return the last digit of n 1:lowbit(n) = n & -n

14. Double pointer algorithm

for (int i = 0, j = 0; i < n; i ++ )
{
    
    
    while (j < i && check(i, j)) j ++ ;

    // 具体问题的逻辑
}

Common problem classification:
(1) For a sequence, use two pointers to maintain an interval
(2) For two sequences, maintain a certain order, such as the operation of merging two ordered sequences in merge sort

15. Discretization

vector<int> alls; // 存储所有待离散化的值
sort(alls.begin(), alls.end()); // 将所有值排序
alls.erase(unique(alls.begin(), alls.end()), alls.end());   // 去掉重复元素

// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
    
    
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
    
    
        int mid = l + r >> 1;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return r + 1; // 映射到1, 2, ...n
}

16. Interval merge

// 将所有存在交集的区间合并
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;
}

Guess you like

Origin blog.csdn.net/weixin_45629285/article/details/110350640