ACM常用模板套用

素数判定

常规法
返回的类型是bool型,时间复杂度是O( sqrt(n) );

bool isprime(int x)
{
	if(x==1) return false;
	for(int i= 2; i <= sqrt(x);++i)
	{
		if(x%i == 0) return false;
	}
	return true;
}

欧拉筛法
时间复杂度最小O(n) 。
数开的过大也会TL。

调用函数 prime(MAX);  可以求MAX以内的素数,存放在数组primenum[ ]里。
数组num[ ]里,值等于0代表下标是素数(1除外),值等于1代表下标不是素数。
#define MAX 100000005
int t = 0, primenum[MAX], num[MAX] = {0};
void prime(int n)
{
	for(int i = 2; i <= n; i++)
	{
		if(!num[i])	primenum[++t] = i;
		for(int j = 1; j <= t&&primenum[j] * i <= n; j++)
		{
			num[i * primenum[j]] = true;
			if(i % primenum[j] == 0) break;
		}
	}
}

组合计数函数

公式法
直接套用数学公式求解。

long long combin(long long n, long long k)
{
	if(k > n) return 0;
	if(k > n-k) k = n - k;
	long long m = 1, s = 1;
	for(int i = 0; i < k; i++)
	{
		m = m * (n - i);
		s = s * (i + 1);
	}
	return m/s;
}

递推实现组合函数

int combin(int n, int k)
{
    if(k > n)
        return 0;
    else if(k == n||k == 0)
        return 1;
    else
        return combin(n-1,k) + combin(n-1, k-1);
}

拓扑排序

我们都知道一个师傅可以有很多徒弟,一个徒弟也可以有很多师傅,这是合法的。然而,一些师徒持有非法关系。以a和b为例,a是b的师傅,同时b也是a的师傅,这是违法的!为了避免这种情况,请帮助我们判断他们的关系是否合法。
请注意,师徒关系是可传递的。这意味着如果A是B的师傅,B是C的师傅,那么A也是C的师傅。
判断是否存在有向环

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int n,m;
int vis[110];
vector<int> g[110];
bool topo()
{
	queue<int> q;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])
			q.push(i);
	}
	int k=0;
	while(!q.empty())
	{
		k++;
		int now=q.front();
		q.pop();
		for(auto to:g[now] )
		{
			vis[to]--;
			if(!vis[to])
			{
				q.push(to);
			}
		}
	}
	if(n==k)
		return true;
	else
		return false;
}
int main()
{
	while(~scanf("%d %d",&n,&m),n,m)
	{
		memset(vis,0,sizeof(vis));
		memset(g,0,sizeof(g));
		int a,b;
		for(int i=0;i<m;i++)
		{
			scanf("%d %d",&a,&b);
			g[a].push_back(b);
			vis[b]++;
		}
		bool ans = topo();
		if(ans)
			cout<<"YES"<<endl;
		else 
			cout<<"NO"<<endl;
	}
	return 0;
}


快速幂

原理类似二分法,复杂度是log(N).

下面展示一些 内联代码片

const ll mod = 1e9+7;
ll pow(ll x, ll y)
{
	ll res = 1;
	while(y)
	{
		if(y&1)	
			res = res*x%mod;
		x = x*x%mod;
		y=y>>1;
	}
	return res;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值