一.取余
(1)两数相加取余:
(a + b) % p = (a % p + b % p) % p
(2)两数相减取余:
(a - b) % p = (a % p - b % p) % p
a或者b小于零的情况下对p取余看,
a每次加p直到为正数为止,再对p取余
代码:
#include <bits/stdc++.h>
using namespace std;
int abs(int a, int b) {
while (a < 0) {
a += b;
}
return a;
}
int mode(int a, int b) {
if (a >= 0) {
return a % b;
}
else {
return abs(a, b) % b;
}
}
int main()
{
cout << mode(-2, 5) << endl;
return 0;
}
(3)两数相乘取余:
(a * b) % p = (a % p * b % p) % p
(4)两数相除取余:
逆元法
( A / B ) % C
= ( A * B^(-1) ) % C
= ((A % C) * ( B^(-1) %C ))%C
( B ^ ( -1 ) ) % C
如果 B C 互质 则存在一个整数X 使得 b^( -1 ) ≡ X ( mod C ) 则 X 称为 B 模 C 的乘法逆元
记 X = B^(-1) BX ≡ 1(mod C)
例
(2/5)%7
= ( ( 2%7) * ( 5^(-1) %7) ) %7 // 5 与 7 互质 当 X = 3 时 ( 5*3 ) mod C = 1
=(( 2 % 7) * (3 % 7) ) % 7
= 6
二:快速幂
对于任意求幂
M^(N)
= M^(X1+X2+X3..+Xn)
=M^(X1) * M(X2)... * M(Xn)
=M^( 2 ^ (n) * j) * M^( 2 ^ (n-1) * j) *...*M^( 2 ^ (0) * j)
//j 为 N二进制第 n 位上的值
//循环 维护 2^(n) 的值
例:
3^(13)
13的二进制为 1101
3^(13)
=3^(8 * 1) * 3^(4 * 1) * 3^(2 * 0) * 3^(1 * 1)
=3^(2^(3) * 1) * 3^(2^(2) * 1) * 3^(2^(1) * 0) * 3^(2^(0) * 1)
代码
int pow(int n, int X,int max) {
int re = 1, a = n;
while (X != 0) {
if (X % 2) {
re *= n;
re %= max;
}
n *= n;
n %= max;
X /= 2;
}
return re;
}
三:阶乘取模
a!%b
当 a 的值大于等于 b 的最大质因数时 值为0
例如
a! % 666 666 最大的质因数为 111 所以当 a>=111 时 a!666 = 0
四:大数取余
使用数组模拟,按位单独取余 再求和即可
int Mode(char* s, int len,int n) {
int i, x = 1;
int sum = 0;
for (i = 0; len - 1 - i >= 0; i++) {
sum += (s[len - i - 1] - '0') * x % n;
x *= 10;
sum %= n;
}
return sum;
}
五:C++STL库
(1)可变数组vector
#include <bits/stdc++.h>
using namespace std;
int main()
{
vector<int> arr;//定义vector数组 初始长度为0
cout << arr.size() << endl;//数组长度
arr.push_back(10);//在数组尾部添加一个元素
if (arr.size() != 0) {
arr.pop_back();//删除尾部的一个元素 只有数组中有元素时才能进行此操作
}
for (int i = 0; i < arr.size(); i++) {
cout << arr[i] << " ";// 遍历数组 与普通数组一样
}
for (auto i : arr) {
cout << i << " ";//增强版for
}
return 0;
}
(2)字符串 string
#include <bits/stdc++.h>
using namespace std;
int main()
{
string a, b;
//字符串拼接
a = "Hello";
b = " World";
a += b;
cout << a << endl; //输出的值为 Hello World
sort(a.begin(), a.end());//排序
reverse(a.begin(), a.end());//反转字符串
return 0;
}
(3)队列 queue
#include <bits/stdc++.h>
using namespace std;
int main()
{
queue<int> qu;//新建队列
cout << qu.size() << endl;// 队列长度
qu.push(5);//添加元素
if (qu.size() > 0) {//当队列不为空时才能访问
cout << qu.front() << endl;
}
if (qu.size() > 0) {
qu.pop();//出队 当队列不为空时
}
return 0;
}
(4)栈 stack
#include <bits/stdc++.h>
using namespace std;
int main()
{
stack<int> sta;//新建栈
cout << sta.size() << endl;//获取栈大小
sta.push(2);//入栈
if (sta.size() > 0) {
cout << sta.top() << endl;//获取栈顶元素
}
if (sta.size() != 0) {
sta.pop();//出栈
}
return 0;
}
(5) set 一个 去重 有序 的集合
#include <bits/stdc++.h>
using namespace std;
int main()
{
set<int> se;
se.insert(10);//插入元素
int len = se.size();//获取大小
se.erase(1);//删除元素 如果没有则不删除
int min = *se.begin();//获取集合最小值
int max = *se.rbegin();//获取集合最大值
se.count(5);//查询值是否存在
for (auto i : se) {//遍历
cout << i << endl;
}
return 0;
}