基础算法模板总结

基础算法模板总结

归并排序

void merge_sort(int l,int r){
	if(l>=r) return;
	int mid=l+r>>1;
	merge_sort(l,mid);
	merge_sort(mid+1,r);
	//和并
	int i=l,j=mid+1,k=0,temp[N];
	while(i<=mid&&j<=r){
		if(a[i]>=a[j]){
			temp[k++]=a[j++];
		}else{
			temp[k++]=a[i++];
		}
	}
	//剩余部分加入
	while(i<=mid) temp[k++]=a[i++];
	while(j<=r) temp[k++]=a[j++];
	//赋值
	for(int k=0,i=l;i<=mid;i++,k++){
		a[i]=temp[k];
	}
	return;
}
二分模板
  • condition1,check时需要左边
int l=0,r=n-1;
while(l<r){
	int mid=l+r>>1;
	if(check(mid)) r=mid;
	else l=mid+1;
}
  • condition2,check时候需要右边
int l=0,r=n-1;
while(l<r){
	int mid=l+r+1>>1;
	if(check(mid)) l=mid;
	else r=mid-1;
}
前缀矩阵和模板
#include<iostream>
#include<algorithm>
#include<string>
#include <vector>
using namespace std;
#define Long Long int
const int N = 1010;

int n,m,q;
int arr[N][N],s[N][N];

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++){
        for (int j = 1; j <= m; ++j) {
            cin>>arr[i][j];
        }
    }
    //前缀矩阵和
    for(int i=1;i<=n;i++){
        for (int j = 1; j <= m; ++j) {
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+arr[i][j];
        }
    }
    while(q--){
        int x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        int res=s[x2][y2]-s[x1][y2-1]-s[x2-1][y1]+s[x1-1][y1-1];
        cout<<res<<endl;
    }
    return 0;
}
差分和差分矩阵模板
  • 差分
    在这里插入图片描述
#include<iostream>
#include<algorithm>
#include<string>
#include <vector>
using namespace std;
#define Long Long int
const int N = 100010;

int n,m,arr[N],b[N];
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
        b[i]=arr[i]-arr[i-1];
    }
    while(m--){
        int l,r,c;
        cin>>l>>r>>c;
        b[l]+=c;
        b[r+1]-=c;
    }
    for (int i = 1; i <= n; ++i) {
        arr[i]=arr[i-1]+b[i];
    }
    for (int i = 1; i <= n; ++i) {
        cout<<arr[i]<<" ";
    }
    return 0;
}
  • 差分矩阵

在这里插入图片描述

#include<iostream>
#include<cstdio>
using namespace std;
const int N = 1e3 + 10;
int a[N][N], b[N][N];



int n,m,q;


int 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);
    }
    //求a矩阵变化后结果
    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<<b[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
二分
  • first

在这里插入图片描述

#include <iostream>
#include <algorithm>
using namespace std;
const int N=1000010;

int main(){
    ios::sync_with_stdio(false);
    int a[N],num[N];
    int n,r=0;
    cin>>n;
    for (int i = 0,j=0; i < n; ++i) {
        cin>>a[i];
        num[a[i]]++;
        while(num[a[i]]>1) num[a[j++]]--;
        r= max(i-j+1,r);
    }
    cout<<r;
}
  • second

在这里插入图片描述

#include <iostream>
const int N=100100;

using namespace std;
int main(){
    int n,m,x;
    cin>>n>>m>>x;
    int A[N],B[N];
    for(int i=0;i<n;i++){
        cin>>A[i];
    }
    for (int i = 0; i < m; ++i) {
        cin>>B[i];
    }
    for (int i = 0,j=m-1; i < n; ++i) {
        while(A[i]+B[j]>=x) {
            if(A[i]+B[j]==x) cout<<i<<" "<<j;
            j--;
        }
    }
    return 0;
}
  • 3

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hGKBb2tS-1692520512464)(C:\Users\黄凯\AppData\Roaming\Typora\typora-user-images\image-20230820162657976.png)]

#include <iostream>
#include <algorithm>

using namespace std;
const int N=100100;

int main(){
    int n,m;
    cin>>n>>m;
    int p[n+1],arr[m+1];
    for(int i=0;i<n;i++){
        cin>>p[i];
    }
    for (int i = 0; i < m; ++i) {
        cin>>arr[i];
    }
    int i,j;
    for(i=0,j=0;i<n;i++){
        while(j<m&&arr[j]!=p[i]) j++;
        if(j>=m) break;
        j++;
    }
    cout<<((i==n)?"Yes":"No");
    return 0;
}
位运算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I08nOVXl-1692520512465)(C:\Users\黄凯\AppData\Roaming\Typora\typora-user-images\image-20230820163013526.png)]

#include <iostream>

using namespace std;


int lowbit(int x){
    return x&(-x);
}

int main(){
    int n;
    cin>>n;
    while(n--){
        int a;
        cin>>a;
        int res=0;
        while(a) {
            a-= lowbit(a);
            res++;
        }
        cout<<res<<" ";
    }
    return 0;
}

离散化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bVnZMcft-1692520512466)(C:\Users\黄凯\AppData\Roaming\Typora\typora-user-images\image-20230820163112684.png)]

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int,int> PII;

const int N=300010;
vector<PII> add,query;
vector<int> parm;
int a[N],s[N];
int find(int x){
    int l=0,r=parm.size()-1;
    while(l<r){
        int mid=(l+r)>>1;
        if(parm[mid]>=x) r=mid;
        else l=mid+1;
    }
    return r+1;
}

int main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++){
        int x,c;
        cin>>x>>c;
        add.push_back({x,c});
        parm.push_back(x);
    }
    for (int i = 0; i < m; ++i) {
        int l,r;
        cin>>l>>r;
        query.push_back({l,r});
        parm.push_back(l);
        parm.push_back(r);
    }
    sort(parm.begin(),parm.end());
    parm.erase(unique(parm.begin(),parm.end()),parm.end());
    //放入数组
    for(auto item:add){
        int k= find(item.first);
        a[k]+=item.second;
    }
    //前缀和
    for (int i = 1; i <= parm.size(); ++i) {
        s[i]=s[i-1]+a[i];
    }

    for(auto item:query){
        int fir= find(item.first),sec= find(item.second);
        cout<<s[sec]-s[fir-1]<<endl;
    }
    return 0;
}
区间合并

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j1EGKfTj-1692520512466)(C:\Users\黄凯\AppData\Roaming\Typora\typora-user-images\image-20230820163242777.png)]

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int,int> PII;//

const int N=1001000;

vector<PII> eg,res;

int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int l,r;
        cin>>l>>r;
        eg.push_back({l,r});
    }
    sort(eg.begin(),eg.end());
    int st=-2e9,ed=-2e9;
    for(auto item:eg){
        if(item.first>ed){
            if(ed!=-2e9) res.push_back({st,ed});
            st=item.first,ed=item.second;
        }
        else if(item.second>=ed){
            ed=item.second;
        }
    }
    res.push_back({st,ed});
    cout<<res.size();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值