#include<bits/stdc++.h>
using namespace std;#defineIOSios::sync_with_stdio(false);cin.tie(0);cout.tie(0)typedeflonglong ll;typedef pair<int,int> PII;int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
最大公约数函数
intgcd(int a,int b){return b?gcd(b, a%b):a;}
质数筛法
求解1~n中有多少个素数
//埃氏筛法 (略)//线性筛法 (因为比较叼就决定用他了)constint N =1e6+10;int cnt,prime[N];
bool st[N];voidget_prime(int n){for(int i =2; i <= n; i ++){if(!st[i]) prime[cnt ++]= i;for(int j =0; prime[j]<= n/i; j ++){
st[prime[j]*i]= true;if(i % prime[j]==0)break;}}}//时间复杂度O(n), cnt为1~n中的质数个数,大约为n/ln n。//prime数组存放的是素数
分解质因数
输入:
6
输出:
2131voidget_divisors(int x){for(int i =2; i <= x/i; i ++){if(x % i ==0){int s =0;while(x % i ==0){
x /= i;
s ++;}
cout << i <<" "<< s << endl;}}if(x >1) cout << x <<" "<<1<< endl;//输出大于根号x的约数
cout << endl;}
约数个数以及约数之和
//应用了上述的分解质因数 此处的s更新为哈希表存下了每一个i所对应的s = mp[i]
unordered_map<int,int> mp;voidget_divisors(int x){for(int i =2; i <= x/i; i ++){if(x % i ==0){while(x % i ==0){
x /= i;
mp[i]++;}}}if(x >1) mp[x]++;}//约数个数 将每一个质因数的个数+1 相乘累积在一起
ll ans =1;for(auto i = mp.begin(); i != mp.end(); i ++){
ans = ans*(i->second +1)%mod;}// ans为该数的约数个数之和//约数之和 6 = 2^1 * 3^1 约数之和1+2+3+6=12 算法: (2^0+2^1)*(3^0+3^1) = 12
ll ans =1;for(auto i = mp.begin(); i != mp.end(); i ++){
ll a = i->first, b = i->second, t =1;while(b --) t =(t*a+1)%mod;
ans = ans*t%mod;}// ans为该数的约数之和
快速幂
ll quickpow(ll a,ll b)//a^b % p 利用a^b = (a^2)^b/2减少幂的次数{
ll ans =1, base = a;while(b){if(b &1) ans = ans * base % mod;
base = base * base % mod;
b >>=1;}return ans;}
快速乘
ll quickmul(ll a,ll b)//(a+b) % p 用a*b = 2a*b/2减少加的次数{
ll ans =0, base = a;while(b){if(b &1) ans =(ans + base)% mod;
base =(base + base)% mod;
b >>=1;}return ans;}
大数相乘取余运算(结合快速幂和快速和)
计算72356825451438的53727354327038次方 %27335634901889#include<iostream>
using namespace std;typedeflonglong ll;const ll mod =27335634901889;
ll quickadd(ll a,ll b,ll mod){
ll ans =0, base = a;while(b){if(b &1) ans =(ans+base)%mod;
base =(base+base)%mod;
b >>=1;}return ans;}
ll quickpow(ll a,ll b,ll mod){
ll ans =1, base = a;while(b){if(b &1) ans =quickadd(ans,base,mod);//此处 base*bae会溢出 使用快速和不会溢出
base =quickadd(base,base,mod);
b >>=1;}return ans;}intmain(){
cout <<quickpow(72356825451438,53727354327038,mod)<< endl;return0;}
求逆元(快速幂)
//定义:满足a/b ≡ a*x(mod p)式子时,x = b^-1; 则称x为b的模p逆元/*
b存在乘法逆元的充要条件是 b 与模数 p 互质。否则不存在乘法逆元。
且当模数 m 为质数时,b^m−2 即为 b 的乘法逆元。
*/
求 b模p的乘法逆元就是 (b^(p-2))% p
使用快速幂即可
堆(优先队列)
#include<bits/stdc++.h>
using namespace std;
priority_queue <int, vector<int>, greater<int>> q;//优先队列,从小到大排序//priority_queue<int> 默认为priority_queue<int, vector<int>, less<int>> 从大到小排序intmain(){int n; cin >> n;for(int i =1; i <= n; i ++){int x; cin >> x;
q.push(x);}int ans =0;while(q.size()!=1){int a = q.top(); q.pop();int b = q.top(); q.pop();
ans +=(a+b);
q.push(a+b);}
cout << ans << endl;return0;}
二分
二分后 满足左边 去掉右边区域
while(l < r){int mid = l + r >>1;if(check()) r = mid;else l = mid +1;}
二分后 满足右边 去掉左边区域
while(l < r){int mid = l + r +1>>1;if(a[mid]<= k) l = mid;else r = mid-1;}
BFS
采用队列来做
1.起点和终点 不一定是按题目来
2.如果起点有多个x,y,先把起点全部先push进去,bfs里面再直接while(q.size()){...}#include<iostream>#include<cstring>#include<queue>
using namespace std;typedef pair<int,int> PII;constint N =110;int a[N][N],d[N][N];int n,m;intbfs(){
queue<PII>q;
q.push({0,0});memset(d,-1,sizeof(d));
d[0][0]=0;int dx[]={-1,0,1,0},dy[]={0,1,0,-1};while(q.size()){
PII t = q.front();
q.pop();for(int i =0; i <4; i ++){int x = t.first+dx[i],y = t.second+dy[i];if(x>=0&& x<=n-1&& y>=0&& y<=m-1&& d[x][y]==-1&& a[x][y]==0){
d[x][y]= d[t.first][t.second]+1;
q.push({x,y});}}}return d[n-1][m-1];}intmain(){
cin >> n >> m;for(int i =0; i < n; i ++)for(int j =0; j < m; j ++)
cin >> a[i][j];
cout <<bfs()<< endl;return0;}