算法基础课——基础算法(模板整理)

 快速排序

快速排序

#include 
#include 
using namespace std;
int n;
int s[100000];
int main()
{
    cin>>n;
    for(int i=0;i>s[i];
    }
    sort(s,s+n);
    for(int i=0;i

第K个数

#include 
#include 
using namespace std;
int a[100005];
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    nth_element(a+1,a+k,a+1+n);
    cout<

归并排序 

归并排序

#include 
using namespace std;
const int N = 100010;
int n;
int q[N],tmp[N];
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=1,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(int i=l,j=1;i<=r;i++,j++)
    {
        q[i]=tmp[j];
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&q[i]);
    }
    merge_sort(q,1,n);
    for(int i=1;i<=n;i++)
    {
        printf("%d ",q[i]);
    }
    return 0;
}

逆序对的数量

#include 
using namespace std;
typedef long long ll;
const int N = 100010;
int n;
int q[N],tmp[N];
ll merge_sort(int l,int r)
{
    if(l>=r)
    {
        return 0;
    }
    int mid = (l+r)>>1;
    ll res=merge_sort(l,mid)+merge_sort(mid+1,r);
    //归并的过程
    int k=1,i=l,j=mid+1;
    while(i<=mid&&j<=r)
    {
        if(q[i]<=q[j])
        {
            tmp[k++]=q[i++];
        }
        else
        {
            tmp[k++]=q[j++];
            res+=(mid-i+1);
        }
    }
    //扫尾
    while(i<=mid)
    {
        tmp[k++]=q[i++];
    }
    while(j<=r)
    {
        tmp[k++]=q[j++];
    }
    //物归原主
    for(int i=l,j=1;i<=r;i++,j++)
    {
        q[i]=tmp[j];
    }
    return res;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>q[i];
    }
    cout<

二分 

数的范围

#include 
using namespace std;
const int N = 100010;
int q[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i>q[i];
    }
    while(m--)
    {
        int x;
        cin>>x;
        int l=0,r=n-1;
        while(l>1;
            if(q[mid]>=x)
            {
                r=mid;
            }
            else l=mid+1;
        }
        if(q[l]!=x)
        {
            cout<<"-1 -1"<>1;
                if(q[mid]<=x)
                {
                    l=mid;
                }
                else r=mid-1;
            }
            cout<

数的三次方根

#include 
using namespace std;
int main()
{
    double n;
    cin>>n;
    double l=-10000,r=10000;
    while(r-l>1e-8)
    {
        double mid = (l+r)/2;
        if(mid*mid*mid>=n)
        {
            r=mid;
        }
        else l=mid;
    }
    printf("%.6lf\n",l);
    return 0;
}

高精度

 高精度加法

Python一行就可以解决

print(int(input())+int(input()))
#include 
#include 
#include 
using namespace std;
vector add(vector &A,vector &B)
{
    vectorC;
    int t=0;
    for(int i=0;i>a>>b;
    vectorA,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');
    }
    auto C = add(A,B);
    for(int i=C.size()-1;i>=0;i--)
    {
        cout<

高精度减法

#include 
#include 
#include 
using namespace std;
//判断是否有A>=B
bool cmp(vector &A,vector &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;
}
//C=A-B
vector sub(vector &A,vector &B)
{
    vectorC;
    int t=0;
    for(int i=0;i1&&C.back()==0)
    {
        C.pop_back();
    }
    return C;
}
int main()
{
    string a,b;
    cin>>a>>b;
    vectorA,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--)
        {
            cout<=0;i--)
        {
            cout<

高精度乘法

#include 
#include 
using namespace std;
vector mul(vector& A, int b)
{
    vectorC;
    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;
}
int main()
{
    string a;
    int b;
    cin >> a >> b;
    vectorA;
    for (int i = a.size() - 1; i >= 0; i--)
    {
        A.push_back(a[i] - '0');
    }
    auto C = mul(A, b);
    for (int i = C.size() - 1; i >= 0; i--)
    {
        cout << C[i];
    }
    return 0;
}

高精度除法

#include 
#include 
#include 
using namespace std;
vector div(vector& A, int b,int &r)
{
    vectorC;
    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;
    vectorA;
    for (int i = a.size() - 1; i >= 0; i--)
    {
        A.push_back(a[i] - '0');
    }
    int r;
    auto C = div(A, b,r);
    for (int i = C.size() - 1; i >= 0; i--)
    {
        cout << C[i];
    }
    cout<

前缀和与差分

前缀和

#include 
using namespace std;
const int N = 100005;
int a[N],s[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        s[i]=s[i-1]+a[i];
    }
    while(m--)
    {
        int l,r;
        cin>>l>>r;
        cout<

子矩阵的和

#include 
using namespace std;
const int N = 1010;
int a[N][N], s[N][N];
int main() 
{
    int n, m, q;
    cin >> n >> m >> q;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            scanf("%d", &a[i][j]);
            s[i][j] = s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1] + a[i][j]; // 求前缀和
        }
    while (q--) 
    {
        int x1,y1,x2,y2;
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        // 算子矩阵的和
        printf("%d\n", s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1]); 
    }
    return 0;
}

差分

#include 
using namespace std;
const int N = 100010;
int n,m;
int a[N],b[N];
void insert(int l,int r,int c)
{
    b[l]+=c;
    b[r+1]-=c;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++)
    {
        insert(i,i,a[i]);
    }
    while(m--)
    {
        int l,r,c;
        cin>>l>>r>>c;
        insert(l,r,c);
    }
    for(int i=1;i<=n;i++)
    {
        b[i]+=b[i-1];
    }
    for(int i=1;i<=n;i++)
    {
        cout<

差分矩阵

#include 
using namespace std;
const int N = 1010;
int n,m,q;
int a[N][N],b[N][N];
void insert(int x1,int y1,int x2,int y2,int c)
{
    b[x1][y1]+=c;
    b[x2+1][y1]-=c;
    b[x1][y2+1]-=c;
    b[x2+1][y2+1]+=c;
}
int main()
{
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            insert(i,j,i,j,a[i][j]);
        }
    }
    while(q--)
    {
        int x1,y1,x2,y2,c;
        cin>>x1>>y1>>x2>>y2>>c;
        insert(x1,y1,x2,y2,c);
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cout<

双指针算法

最长连续不重复子序列

#include 
using namespace std;
const int N = 100010;
int n;
int a[N],s[N];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    int res=0;
    for(int i=1,j=1;i<=n;i++)
    {
        s[a[i]]++;
        while(s[a[i]]>1)
        {
            s[a[j]]--;
            j++;
        }
        res=max(res,i-j+1);
    }
    cout<

数组元素的目标和

#include 
using namespace std;
const int N = 100005;
int n,m,x;
int a[N],b[N];
int main()
{
    cin>>n>>m>>x;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>b[i];
    }
    for(int i=1,j=m;i<=n;i++)
    {
        while(j>=1&&a[i]+b[j]>x) j--;
        if(a[i]+b[j]==x)
        {
            cout<

判断子序列

#include 
using namespace std;
const int N = 100005;
int n,m;
int a[N],b[N];
int main()
{
    cin>>n>>m;
    for(int i=0;i>a[i];
    }
    for(int i=0;i>b[i];
    }
    int i=0,j=0;
    while(i

位运算

二进制中1的个数

#include 
using namespace std;
int lowbit(int x)
{
    return x & -x;
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        int x;
        cin>>x;
        int res=0;
        while(x)
        {
            x-=lowbit(x);
            res++;
        }
        cout<

离散化

区间和

#include 
#include 
#include 
using namespace std;
const int N = 300010; //n次插入和m次查询相关数据量的上界
int n, m;
int a[N];//存储坐标插入的值
int s[N];//存储数组a的前缀和
vector alls;  //存储(所有与插入和查询有关的)坐标
vector> add, query; //存储插入和询问操作的数据

int find(int 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;
}

int main() 
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) 
    {
        int x, c;
        scanf("%d%d", &x, &c);
        add.push_back({x, c});
        alls.push_back(x);
    }
    for (int i = 1; i <= m; i++) 
    {
        int l , r;
        scanf("%d%d", &l, &r);
        query.push_back({l, r});
        alls.push_back(l);
        alls.push_back(r);
    }
    //排序,去重
    sort(alls.begin(), alls.end());
    alls.erase(unique(alls.begin(), alls.end()), alls.end());
    //执行前n次插入操作
    for (auto item : add) 
    {
        int x = find(item.first);
        a[x] += item.second;
    }
    //前缀和
    for (int i = 1; i <= alls.size(); i++) s[i] = s[i-1] + a[i];
    //处理后m次询问操作
    for (auto item : query) 
    {
        int l = find(item.first);
        int r = find(item.second);
        printf("%d\n", s[r] - s[l-1]);
    }

    return 0;
}

区间和并

区间和并

#include 
#include 
#include 
using namespace std;
typedef pairpii;
const int N = 100010;
int n;
vectorsegs;
void merge(vector&segs)
{
    vectorres;
    sort(segs.begin(),segs.end());
    int st=-2e9,ed=-2e9;
    for(auto seg:segs)
    {
        if(ed>n;
    for(int i=0;i>l>>r;
        segs.push_back({l,r});
    }
    merge(segs);
    return 0;
}

你可能感兴趣的:(算法竞赛从入门到入土,c++,算法,数据结构)