Basic algorithm of acm

I finally finished the basic algorithm template. Liver!!!

The following sorting template may be used in the interview, but it is basically replaced by sort in acm.

I will match each template below with a question to practice my hands.


Fast platoon training

Quick layout template

void quick_sort(int a[], int l, int r)
{
    if (l >= r)
        return;
    int flag = a[(l+r)/2], i = l - 1, j = r + 1;
    while (i < j)
    {
        do
            i++;
        while (a[i] < flag);
        do
            j--;
        while (a[j] > flag);
        if (i < j)
            swap(a[i], a[j]);
        else
            break;
    }
    quick_sort(a, l, j);
    quick_sort(a, j + 1, r);
}

Merge sort

Merge sort template

void merge_sort(int a[], int l, int r)
{
    if (l >= r)
        return;
    int mid = (l + r) / 2;
    merge_sort(a, l, mid);
    merge_sort(a, mid + 1, r);
    int k = 0, i = l,j = mid + 1;
    while (i <= mid && j <= r)
    {
        if (a[i] < a[j])
            tmp[k++] = a[i++];
        else
            tmp[k++] = a[j++];
    }
    while (i <= mid)
        tmp[k++] = a[i++];
    while (j <= r)
        tmp[k++] = a[j++];
    for (i = l, j = 0; i <= r; ++i, ++j)
        a[i] = tmp[j];
}

Integral dichotomy

Integer dichotomy template

// Integer binary algorithm template

bool check(int x) {/* ... */} // Check whether x satisfies certain properties

// When the interval [l, r] is divided into [l, mid] and [mid + 1, r], use:
int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check() to determine whether the mid meets the nature
        else l = mid + 1;
    }
    return l;
}
// When the interval [l, r] is divided into [l, mid - 1] and [mid, r], use:
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;
}

Floating point dichotomy

Floating point binary template

// Floating point binary algorithm template

bool check(double x) {/* ... */} // Check whether x satisfies certain properties

double bsearch_3(double l, double r)
{
    const double eps = 1e-6;   // The accuracy of eps depends on the requirement of the subject for accuracy
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

Large integer addition

Large integer addition template

vector<int> add(vector<int> &a, vector<int> &b)
{
    vector<int> c;
    int up = 0;
    for (int i = 0; i < a.size() || i<b.size(); ++i)
    {
        if (i < a.size())
            up += a[i];
        if (i < b.size())
            up += b[i];
        c.push_back(up % 10);
        up /= 10;
    }
    while (up>0)
    {
        c.push_back(up % 10);
        up /= 10;
    }
    return c;
}

Large integer subtraction template

Given two positive integers, calculate their difference, and the result may be negative.

Input format
 There are two lines, each containing an integer.

Output format
 A total of one line, including the difference.

Data range
 1 ≤ integer length ≤ 105
 Input example:
32
11
 Output example:
21

#include <iostream>
#include <vector>
using namespace std;
bool cmp(vector<int> &a, vector<int> &b)
{
    if (a.size() != b.size())
        return a.size() > b.size();
    for (int i = a.size() - 1; i >= 0; --i)
        if (a[i] != b[i])
            return a[i] > b[i];
    return true;
}
vector<int> sub(vector<int> &a, vector<int> &b)
{
    vector<int> c;
    for (int i = 0, up = 0; i < a.size(); ++i)
    {
        up = a[i] - up;
        if (i < b.size())
            up = up - b[i];
        c.push_back((up + 10) % 10);
        if (up < 0)
            up = 1;
        else
            up = 0;
    }
    while(c.size()>1&&c.back()==0)
    c.pop_back();
    return c;
}
int main()
{
    string a, b;
    vector<int> A, B;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; --i)
        A.push_back(a[i] - '0');
    for (int i = b.size() - 1; i >= 0; --i)
        B.push_back(b[i] - '0');
    if(cmp(A,B))
    {
        auto C=sub(A,B);
        for (int i = C.size() - 1; i >= 0; --i)
        printf("%d", C[i]);
    }
    else
    {
        printf("-");
        auto C=sub(B,A);
        for (int i = C.size() - 1; i >= 0; --i)
        printf("%d", C[i]);
    }
    cout << endl;
    return 0;
}

High precision multiplication template

Given two positive integers A and B, please calculate the value of A * B.
    
Input format
 There are two lines in total. The first line contains the integer A, and the second line contains the integer B.

Output format
 A total of one line, containing the value of A * B.

Data range
 1 ≤ A length ≤ 100000,
0≤B≤10000
 Input example:
2
3
 Output example:
6
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
using namespace std;
const int cmax = 1e6 + 5;
int a[cmax], b[cmax], sum[cmax];
int main()
{
    memset(a, 0, sizeof(a));
    memset(b, 0, sizeof(b));
    memset(sum, 0, sizeof(sum));
    string astr, bstr;
    cin >> astr >> bstr;
    for (int i = astr.size() - 1, j = 0; i >= 0; --i, ++j)
        a[j] = astr[i] - '0';
    for (int i = bstr.size() - 1, j = 0; i >= 0; --i, ++j)
        b[j] = bstr[i] - '0';
    int alen = astr.size();
    int blen = bstr.size();
    for (int i = 0; i < alen; ++i)
        for (int j = 0; j < blen; ++j)
            sum[i + j] += a[i] * b[j];
    int up = 0, k = 0;
    while (k < alen + blen - 1)
    {
        sum[k] += up;
        up = sum[k] / 10;
        sum[k++] = sum[k] % 10;
    }
    while (up)
    {
        sum[k++] = up % 10;
        up /= 10;
    }
    if (astr[0]=='0' || bstr[0]=='0')
        cout << "0" ;
    else
        for (int i = k - 1; i >= 0; --i)
            printf("%d", sum[i]);
    cout << endl;
    return 0;
}

High precision division template

Given two nonnegative integers A and B, please calculate the quotient and remainder of A / B.

Input format
 There are two lines in total. The first line contains the integer A, and the second line contains the integer B.

Output format
 There are two lines in total. The first line outputs the quotient and the second line outputs the remainder.

Data range
 1 ≤ A length ≤ 100000,
1≤B≤10000
 B must not be 0

Input example:
7
2
 Output example:
3
1
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
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;
}
int main()
{
    string a;
    int b;
    cin>>a>>b;
    vector<int> A;
    for(int i=a.size()-1;i>=0;--i)
    A.push_back(a[i]-'0');
    int r;
    auto B=div(A,b,r);
    for(auto it=B.rbegin();it!=B.rend();++it)
    printf("%d",*it);
    cout<<endl<<r<<endl;
    return 0;
}

One dimensional prefixes and templates

Enter a sequence of integers of length n.

Next, enter m queries, one pair of l, r for each query.

For each query, the sum of the first number to the r number in the origina l sequence is output.

Input format

The first line contains two integers, n and m.

The second row contains n integers, representing an integer sequence.

Next m lines, each containing two integers l and r, represent the range of a query.

Output format

There are m lines in total, and each line outputs a query result.

Data range

1≤l≤r≤n1≤l≤r≤n,
1≤n,m≤1000001≤n,m≤100000,
- 1000 ≤ value of elements in the sequence ≤ 1000 − 1000 ≤ value of elements in the sequence ≤ 1000

Input example:

5 3
2 1 3 6 4
1 2
1 3
2 4

Output example:

3
6
10
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int cmax = 10e5 + 5;
int a[cmax], sum[cmax];
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
        sum[i] = sum[i - 1] + a[i];
    while (m--)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d\n", sum[r] - sum[l - 1]);
    }
    return 0;
}

2D prefixes and templates

Input an integer matrix with n rows and m columns, and then input q queries. Each query contains four integers x1, y1, x2, y2, representing the upper left and lower right coordinates of a sub matrix.

The sum of all numbers in each query output submatrix.

Input format

The first line contains three integers n, m, q.

Next n lines, each containing m integers, represent an integer matrix.

Next line q, each line containing four integers x1, y1, x2, y2, represents a set of queries.

Output format

There are q lines in total, and each line outputs a query result.

Data range

1≤n,m≤10001≤n,m≤1000,
1≤q≤2000001≤q≤200000,
1≤x1≤x2≤n1≤x1≤x2≤n,
1≤y1≤y2≤m1≤y1≤y2≤m,
- 1000 ≤ value of elements in matrix ≤ 1000 − 1000 ≤ value of elements in matrix ≤ 1000

Input example:

3 4 3
1 7 2 4
3 6 2 8
2 1 2 3
1 1 2 2
2 1 3 4
1 3 3 4

Output example:

17
27
21
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int cmax = 1e3 + 5;
int a[cmax][cmax], sum[cmax][cmax];
int main()
{
    int n, m, q;
    scanf("%d%d%d", &n, &m, &q);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; ++j)
        {
            scanf("%d", &a[i][j]);
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] + a[i][j] - sum[i - 1][j - 1];
        }
    }
    while (q--)
    {
        int x1, y1, x2, y2;
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        printf("%d\n", sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1]);
    }
    return 0;
}

One dimensional difference template

Enter a sequence of integers of length n.

Next, enter m operations, each of which contains three integers, l, r, c, to add c to each number between [l, r] in the sequence.

Please output the sequence after all operations.

Input format

The first line contains two integers, n and m.

The second line contains n integers, representing the sequence of integers.

Next m lines, each containing three integers l, r, c, represent an operation.

Output format

A total of one line, including n integers, representing the final sequence.

Data range

1≤n,m≤1000001≤n,m≤100000,
1≤l≤r≤n1≤l≤r≤n,
−1000≤c≤1000−1000≤c≤1000,
- 1000 ≤ value of element in integer sequence ≤ 1000 − 1000 ≤ value of element in integer sequence ≤ 1000

Input example:

6 3
1 2 2 1 2 1
1 3 1
3 5 1
1 6 1

Output example:

3 4 5 3 4 2
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int cmax = 1e5 + 5;
int a[cmax], sum[cmax];
void insert(int l, int r, int val)
{
    sum[l] += val;
    sum[r + 1] -= val;
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
        insert(i, i, a[i]);
    while (m--)
    {
        int l, r, c;
        scanf("%d%d%d", &l, &r, &c);
        insert(l, r, c);
    }
    for (int i = 1; i <= n; i++)
        sum[i] += sum[i - 1];
    for (int i = 1; i <= n; i++)
        printf("%d ", sum[i]);
    return 0;
}

Two dimensional difference template

Input an integer matrix of n rows and m columns, and then enter q operations. Each operation contains five integers x1, y1, x2, y2, c, where (x1, y1) and (x2, y2) represent the upper left and lower right coordinates of a submatrix.

Each operation adds c to the value of each element in the selected submatrix.

Please output the matrix after all operations.

Input format

The first line contains the integers n,m,q.

Next n lines, each containing m integers, represent an integer matrix.

Next row q, each row contains five integers x1, y1, x2, y2, c, representing an operation.

Output format

There are n lines in total, m integers in each line, indicating the final matrix after all operations are completed.

Data range

1≤n,m≤10001≤n,m≤1000,
1≤q≤1000001≤q≤100000,
1≤x1≤x2≤n1≤x1≤x2≤n,
1≤y1≤y2≤m1≤y1≤y2≤m,
−1000≤c≤1000−1000≤c≤1000,
- 1000 ≤ value of elements in matrix ≤ 1000 − 1000 ≤ value of elements in matrix ≤ 1000

Input example:

3 4 3
1 2 2 1
3 2 2 1
1 1 1 1
1 1 2 2 1
1 3 2 3 2
3 1 3 4 1

Output example:

2 3 4 1
4 3 4 1
2 2 2 2
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int cmax=1e3+5;
int a[cmax][cmax],b[cmax][cmax];
void Differential (int x1,int y1,int x2,int y2,int c)
{
    b[x1][y1]+=c;
    b[x1][y2+1]-=c;
    b[x2+1][y1]-=c;
    b[x2+1][y2+1]+=c;
}
int main()
{
    int n,m,q;
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            scanf("%d",&a[i][j]);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++)
            Differential(i,j,i,j,a[i][j]);
    while(q--)
    {
        int x1,x2,y1,y2,c;
        scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
        Differential(x1,y1,x2,y2,c);
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        b[i][j]+=b[i][j-1]+b[i-1][j]-b[i-1][j-1];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            printf("%d ",b[i][j]);
        printf("\n");
    }
    return 0;
}

Double pointer algorithm (finding the longest continuous common subsequence)

Given a sequence of integers of length n, find the longest continuous interval without repeated numbers and output its length.

Input format

The first line contains the integer n.

The second line contains n integers (all in the range of 0-100000), representing the sequence of integers.

Output format

A total of one line, including an integer, indicating the length of the longest consecutive subsequence without repeating numbers.

Data range

1≤n≤1000001≤n≤100000

Input example:

5
1 2 2 3 5

Output example:

3
#include <bits/stdc++.h>
using namespace std;
const int cmax=1e6+5;
int a[cmax],s[cmax];
int main()
{
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    scanf("%d",&a[i]);
    int res=0;
    for(int i=0,j=0;i<n;++i)
    {
        s[a[i]]++;
        while(s[a[i]]>1)
        {
            s[a[j]]--;
            j++;
        }
        res=max(res,i-j+1);
    }
    printf("%d\n",res);
    return 0;
}

Bit operation (lowbit algorithm)

Given a sequence of length n, please find the number of 1 in the binary representation of each number in the sequence.

Input format

The first line contains the integer n.

The second row contains n integers representing the entire sequence.

Output format

A total of one row, including n integers, where the ith number represents the number of 1 in the binary representation of the ith number in the sequence.

Data range

1≤n≤1000001≤n≤100000,
0 ≤ value of elements in the sequence ≤ 1090 ≤ value of elements in the sequence ≤ 109

Input example:

5
1 2 3 4 5

Output example:

1 1 2 1 2
#include <bits/stdc++.h>
using namespace std;
int lowbit(int x)
{
    return (x & (-x));  //Returns the first 1 of the first right to left number in binary and the 0 after it (returned in decimal)
}
int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        int x, flag = 0;
        scanf("%d", &x);
        while (x)
        {
            x -= lowbit(x);
            flag++;
        }
        cout << flag << " ";
    }
    return 0;
}

If not tired, then my dream is not very cheap

Added by padams on Mon, 08 Jun 2020 06:25:55 +0300