素数判定
常规法
返回的类型是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;
}