c++常用模板(持续更新中)

二分手写

#include<bits/stdc++.h>

using namespace std;

int n,m;
int a[N];
bool f=0;
int FIND(int x)
{
	int l=1,r=n;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(x==a[mid])return mid;
		if(x < a[mid])r=mid-1;
		if(x > a[mid])l=mid+1;
	}
	return -1;
	
}

int main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%lld",&a[i]);
	}
	for(int i=1;i<=m;++i)
	{
		int q;
		cin >> q;
		cout << FIND(q) << " ";
	}
	return 0;
}

二分STL

#include<bits/stdc++.h>

using namespace std;

int n,m;
int a[1000005];

int main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%lld",&a[i]);
	}
	for(int i=1;i<=m;++i)
	{
		int q;
		cin >> q;
		if(a[lower_bound(a+1,a+n+1,q)-a]==q)cout << lower_bound(a+1,a+n+1,q)-a << " ";
		else cout << -1 << " ";
	}
	return 0;
}

Kruskal最小生成树

#include<bits/stdc++.h>

using namespace std;

struct node{
	int to,w,u;
}edge[20005];
bool cmp(node a,node b)
{
	return a.w<b.w; 
}
int n,m;
int u;
int f[20005];
int find(int x)
{
	if(x == f[x])return x;
	f[x]=find(f[x]);
	return f[x];
}
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;++i)f[i]=i;
	for(int i=1;i<=m;++i)cin >> edge[i].u >> edge[i].to >> edge[i].w;
	sort(edge+1,edge+m+1,cmp);
	int cnt=0,ans=0;
	for(int i=1;i<=m;++i)
	{
		if(cnt == n-1)break;
		if(find(edge[i].to)!=find(edge[i].u))
		{
			f[find(edge[i].u)]=find(edge[i].to);
			cnt++;
			ans+=edge[i].w;
		}
	} 
	cout << ans;
	return 0;
	
}

并查集

#include<bits/stdc++.h>

using namespace std;

int n,m;
int z,x,y;
int f[20005];
int find(int x)
{
	if(x == f[x])return x;
	f[x]=find(f[x]);
	return f[x];
}
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;++i)
	{
		f[i]=i;
	}
	for(int i=1;i<=m;++i)
	{
		cin >> z >> x >> y;
		if(z==1)
		f[find(x)]=find(y);
		else
			if(find(x)==find(y))printf("Y\n");
			else printf("N\n");
	}
	return 0;
}

dijkstra堆优化pair版

#include<bits/stdc++.h>
using namespace std;
int n, m, s;//s为出发点
int  vis[100005], dis[100005], u;//flag表示这个点是否被访问过,d表示从起点到下标的最优解u表示当前点
struct node {
	int x, w;//x为编号,w为权值
};
vector<node> G[100005];
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> > q;//定义了从小到大的pair型优先队列
const int inf = 0x3f3f3f;
int main() {
//	freopen("dijkstra.in","r",stdin);
//	freopen("dijkstra.out","w",stdout);
	cin >> n >> m >> s;

	for (int i = 1; i <= n; i++) {
		dis[i] = inf;
	}
	for (int i = 1; i <= m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		G[u].push_back(node{v, w});
	}
//	u = s;//把起点标记为第一个u  
    q.push(make_pair(0,s));//将起点压入q
	dis[s] = 0;
	while (!q.empty()) {//只要还有点没被访问算法就不会结束
	    u=q.top().second;//取队首编号
		vis[u] = 1;
		for (int i = 0; i < G[u].size(); i++) {
			int v = G[u][i].x;//v为编号
			int w = G[u][i].w;//w为权值
			if (!vis[v]&&dis[v]>dis[u]+w) {//如果新的解比原来的解大并且这个点没有被访问就进行松弛操作
				//进行松弛操作,更新最优解
				dis[v]=dis[u]+w;
				q.push(make_pair(dis[v],v));
			}
		}
q.pop();
	}
	for (int i = 1; i <= n; i++) {
		if (dis[i] == inf) {
			printf("2147483647 ");
		} else {
			cout << dis[i] << " ";
		}
	}
	return 0;
}

dijkstra未优化版

#include<bits/stdc++.h>
using namespace std;
int n, m, s;//s为出发点
int  flag[10005], d[10005], u;//flag表示这个点是否被访问过,d表示从起点到下标的最优解u表示当前点
struct node {
	int x, w;//x为编号,w为权值
};
vector<node> G[10005];
const int inf = 0x3f3f3f;
int main() {
	cin >> n >> m >> s;

	for (int i = 1; i <= n; i++) {
		d[i] = inf;
	}
	for (int i = 1; i <= m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		G[u].push_back(node{v, w});
	}
	u = s;//把起点标记为第一个u
	d[s] = 0;
	while (!flag[u]) {//只要还有点没被访问算法就不会结束
		flag[u] = 1;
		for (int i = 0; i < G[u].size(); i++) {
			int v = G[u][i].x;//v为编号
			int w = G[u][i].w;//w为权值
			if (flag[v] == 0) {//如果新的解比原来的解大并且这个点没有被访问就进行松弛操作
				//进行松弛操作,更新最优解
				d[v] = min(d[v], d[u] + w);
			}
		}
		int tmp = 0x3f3f3f3f;
		for (int i = 1; i <= n; i++) {//找最小值
			if (tmp > d[i] && flag[i] == 0) {
				tmp = d[i];
				u = i;//将最小的值作为新的u
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		if (d[i] == 4144959) {
			printf("2147483647 ");
		} else {
			cout << d[i] << " ";
		}
	}
	return 0;

dijkstra堆优化优先队列版

#include<bits/stdc++.h>
using namespace std;
int n, m, s;//s为出发点
int  vis[200005], dis[200005], u;//flag表示这个点是否被访问过,d表示从起点到下标的最优解u表示当前点
struct node {
	int w, x;//x为编号,w为权值
};
vector<node> G[200005];
priority_queue<pair<int, int> > q; //定义了从小到大的pair型优先队列
const int inf = 0x3f3f3f3f;
void dj() {
	dis[s] = 0;
	q.push(make_pair(0, s)); //将起点压入q
	while (!q.empty()) {//只要还有点没被访问算法就不会结束
		u = q.top().second;//取队首编号
		q.pop();
		if (vis[u]) {
			continue;
		}
		vis[u] = 1;
		for (int i = 0; i < G[u].size(); i++) {
			int v = G[u][i].x;//v为编号
			int w = G[u][i].w;//w为权值
			if (dis[v] > dis[u] + w) { //如果新的解比原来的解大并且这个点没有被访问就进行松弛操作
				//进行松弛操作,更新最优解
				dis[v] = dis[u] + w;
				q.push(make_pair(-dis[v], v));

			}
		}

	}
}
int main() {
	cin >> n >> m >> s;
	for (int i = 1; i <= n; i++) {
		dis[i] = inf;
	}
	for (int i = 1; i <= m; i++) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		G[u].push_back(node{w, v});
	}
	dj();
	for (int i = 1; i <= n; i++) {
//		if (dis[i] == inf) {
//			printf("2147483647 ");
//		} else {
			cout << dis[i] << " ";
//		}
	}
	return 0;
}

Floyd

#include <bits/stdc++.h>

#define inf 0x3f3f3f3f

using namespace std;

int g[1005][1005],a,b,c,n,m,k;

int main()
{
    //freopen("floyd.in","r",stdin);
    //freopen("floyd.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(i!=j)g[i][j]=inf;
    for(int i=1;i<=m;i++)
	{
        scanf("%d%d%d",&a,&b,&c);
        g[a][b]=c;
    }
    for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)	
			for(int j=1;j<=n;j++)								
					g[i][j]=min(g[i][k]+g[k][j],g[i][j]);
    for(int i=1;i<=n;i++)
	{
        for(int j=1;j<=n;j++)
        {
        	if(g[i][j]==inf)
			{
        		printf("inf ");
			} 
			else /*if(j!=i)*/printf("%d ",g[i][j]);
		}
        printf("\n");
    }
    return 0;
}

树的深度

#include<bits/stdc++.h>

using namespace std;

vector<int>tree[500005];
int deep[500005];
void dfs(int u,int fa)
{
	for(int i=0;i<tree[u].size();++i)
	{
		int v=tree[u][i];
		if(v == fa)continue;
		deep[v]=deep[u]+1;
		dfs(v,u);
	}
}

int main()
{
	int n;
	cin >> n;
	for(int i=1;i<n;++i)
	{
		int u,v;
		cin >> u >> v;
		tree[u].push_back(v);
		tree[v].push_back(u);	
	}	
	dfs(1,0);
	for(int i=1;i<=n;++i)
	{
		cout << deep[i] << "\n";
	}
	return 0;
}

高精度

#include<stdio.h>
#include<string>
#include<string.h>
#include<iostream>
using namespace std;
//compare比较函数:相等返回0,大于返回1,小于返回-1
int compare(string str1,string str2)
{
    if(str1.length()>str2.length()) return 1;
    else if(str1.length()<str2.length())  return -1;
    else return str1.compare(str2);
}
//高精度加法
//只能是两个正数相加
string add(string str1,string str2)//高精度加法
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    //前面补0,弄成长度相同
    if(len1<len2)
    {
        for(int i=1;i<=len2-len1;i++)
           str1="0"+str1;
    }
    else
    {
        for(int i=1;i<=len1-len2;i++)
           str2="0"+str2;
    }
    len1=str1.length();
    int cf=0;
    int temp;
    for(int i=len1-1;i>=0;i--)
    {
        temp=str1[i]-'0'+str2[i]-'0'+cf;
        cf=temp/10;
        temp%=10;
        str=char(temp+'0')+str;
    }
    if(cf!=0)  str=char(cf+'0')+str;
    return str;
}
//高精度减法
//只能是两个正数相减,而且要大减小
/*string sub(string str1,string str2)//高精度减法
{
    string str;
    int tmp=str1.length()-str2.length();
    int cf=0;
    for(int i=str2.length()-1;i>=0;i--)
    {
        if(str1[tmp+i]<str2[i]+cf)
        {
            str=char(str1[tmp+i]-str2[i]-cf+'0'+10)+str;
            cf=1;
        }
        else
        {
            str=char(str1[tmp+i]-str2[i]-cf+'0')+str;
            cf=0;
        }
    }
    for(int i=tmp-1;i>=0;i--)
    {
        if(str1[i]-cf>='0')
        {
            str=char(str1[i]-cf)+str;
            cf=0;
        }
        else
        {
            str=char(str1[i]-cf+10)+str;
            cf=1;
        }
    }
    str.erase(0,str.find_first_not_of('0'));//去除结果中多余的前导0
    return str;
}
//高精度乘法
//只能是两个正数相乘
string mul(string str1,string str2)
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    string tempstr;
    for(int i=len2-1;i>=0;i--)
    {
        tempstr="";
        int temp=str2[i]-'0';
        int t=0;
        int cf=0;
        if(temp!=0)
        {
            for(int j=1;j<=len2-1-i;j++)
              tempstr+="0";
            for(int j=len1-1;j>=0;j--)
            {
                t=(temp*(str1[j]-'0')+cf)%10;
                cf=(temp*(str1[j]-'0')+cf)/10;
                tempstr=char(t+'0')+tempstr;
            }
            if(cf!=0) tempstr=char(cf+'0')+tempstr;
        }
        str=add(str,tempstr);
    }
    str.erase(0,str.find_first_not_of('0'));
    return str;
}
//高精度除法
//两个正数相除,商为quotient,余数为residue
//需要高精度减法和乘法
void div(string str1,string str2,string &quotient,string &residue)
{
    quotient=residue="";//清空
    if(str2=="0")//判断除数是否为0
    {
        quotient=residue="ERROR";
        return;
    }
    if(str1=="0")//判断被除数是否为0
    {
        quotient=residue="0";
        return;
    }
    int res=compare(str1,str2);
    if(res<0)
    {
        quotient="0";
        residue=str1;
        return;
    }
    else if(res==0)
    {
        quotient="1";
        residue="0";
        return;
    }
    else
    {
        int len1=str1.length();
        int len2=str2.length();
        string tempstr;
        tempstr.append(str1,0,len2-1);
        for(int i=len2-1;i<len1;i++)
        {
            tempstr=tempstr+str1[i];
            tempstr.erase(0,tempstr.find_first_not_of('0'));
            if(tempstr.empty())
              tempstr="0";
            for(char ch='9';ch>='0';ch--)//试商
            {
                string str,tmp;
                str=str+ch;
                tmp=mul(str2,str);
                if(compare(tmp,tempstr)<=0)//试商成功
                {
                    quotient=quotient+ch;
                    tempstr=sub(tempstr,tmp);
                    break;
                }
            }
        }
        residue=tempstr;
    }
    quotient.erase(0,quotient.find_first_not_of('0'));
    if(quotient.empty()) quotient="0";
}
*/

int main()
{
     string str1,str2;
     //string str3,str4;
     cin>>str1>>str2;
     //while()
     //{
         cout<<add(str1,str2)<<endl;
         //cout<<sub(str1,str2)<<endl;
         //cout<<mul(str1,str2)<<endl;
         //div(str1,str2,str3,str4);
         //cout<<str3<<"  "<<str4<<endl;
     //}
     return 0;
}

__int128

快读:
void read(__int128 &n) {
    __int128 x = 0; bool f = false;
    char ch = cin.get();
    while(!isdigit(ch)) {
        if(ch == '-') f = true;
        cin.get(ch);
    }
    while(isdigit(ch)) {
        x = x * 10 + ch - '0';
        cin.get(ch);
    }
    n = f ? -x : x;
}
快写:
void print(__int128 n) {
    if(n < 0) {
        cout.put('-');
        n *= -1;
    }
    if(n > 9) {
        print(n / 10);
    }
    cout.put(n % 10 + '0');
}
主函数
int main()
{
    __int128 a=read(),b=read();
    print(a+b);
    return 0;
}
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值