模板整合
快读:
inline int read() {
int i = 0, j = 1;
char ch = getchar();
while (ch<'0' || ch>'9') { if (ch == '-')j = -1; ch = getchar(); }
while (ch >= '0'&&ch <= '9') i = i * 10 + ch - '0', ch = getchar();
return i*j;
}
快排:
#include <iostream>
#include<algorithm>
using namespace std;
int n, t, a[100010];
void qsort(int l, int r)
{
int i = l, j = r;
int mid = a[(l + r) >> 1];//基准数
while (i <= j) {
while (a[i] < mid)
i++;
while (a[j] > mid)
j--;
if (i <= j) {
swap(a[i], a[j]);
i++; j--;
}
}
if (l < j)qsort(l, j);//递归左边
if (r > i)qsort(i, r);//递归右边
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a, a+n);
for (int i = 0; i < n; i++)
cout << a[i] << " ";
return 0;
}
线性基:
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll a[100010], b[70];
ll n, ans=0;
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i <n; i++)
for (int j = 62; j >= 0; j--)
if (1ll << j & a[i])
if (!b[j]) {
b[j] = a[i];
break;
}
else
a[i] ^= b[j];
for (int i = 62; i >= 0; i--)
ans = max(ans, ans^b[i]);
cout << ans << endl;
return 0;
}
//c++ max函数头文件是#include<algorithm>
DFS:
int dx[] = { 0,1,0,-1 };
int dy[] = { 1,0,-1,0 };
void dfs()//参数用来表示状态
{
if (到达终点状态)
{
...//根据题意来添加
return;
}
if (越界或者是不符合法状态)
return;
for (扩展方式)//一般是四个方向扩展
{
if (扩展方式所达到状态合法)
{
....//根据题意来添加
标记;
dfs();
修改(剪枝);
(还原标记);
//是否还原标记根据题意
//如果加上(还原标记)就是 回溯法
}
}
}
二分:
No.1:最大的小值 1~9中最小的大于5的数
int erf(int le, int ri) {//求满足条件的最大值
while (le + 1 <ri) {//防止死循环
int mid = le + ri >> 1;// '+'优先级大于'>>'
if (check(mid))//check()函数:mid满足条件
le = mid;
else
ri = mid;
}
return le;
}
No.2:最小的大值 1~9中最大的小于5的数
int erf(int le, int ri) {//求满足条件的最小值
while (le + 1 <ri) {//防止死循环
int mid = le + ri >> 1;// '+'优先级大于'>>'
if (check(mid))//check()函数:mid满足条件
ri = mid;
else
le = mid;
}
return ri;
}
快速幂:
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
int qmi(ll a, ll b, ll mod) { //求 a^b%p,时间复杂度 O(logn)
ll flag = 1;
while (b) {
if (b & 1)flag = (flag*a)%mod;
a = (a*a) % mod;
b = b >> 1;
}
return flag%mod;
}
int qji(ll a, ll b, ll mod) { //求 a*b%p,时间复杂度 O(logn)
ll flag = 0;
while (b) {
if (b & 1)flag = (flag + a) % mod;
a = (a << 1) % mod;
b = b >> 1;
}
return flag%mod;
}
int main() {
ll a, b, c;
cin >> a >> b >> c;
cout << a << "^" << b << " mod " << c << "=" << qmi(a, b, c) << "\n";
cout << a << "*" << b << " mod " << c << "=" << qji(a, b, c) << "\n";
return 0;
}
线性筛:
#include<iostream>
#include<algorithm>
#include <cstring>
#include<vector>
#include<math.h>
using namespace std;
int su[10000010];//素数表,默认为0,值为0代表是素数,值为1代表不是素数
bool out[10000010];//判断素数,默认为false 如果值为true,代表这个数不是质数
void aishai(int mm) { //埃式筛法 用时: 3761ms / 内存: 41580KB 一个测试点999ms
su[0] = su[1] = 1;
for (int i = 2; i <= sqrt(mm); i++) {
if (su[i])continue;
for (int j = i << 1; j <= mm; j += i)
su[j] = 1;
}
}
void olshai(int mm) //欧拉筛法 用时: 1654ms / 内存: 18052KB
{
vector<int>cun; //储存素数
out[0]=out[1] = 1; //0和1不是质数 没有,错一个测试点
for (int i = 2; i <= mm; i++)
{
if (!out[i])cun.push_back(i); //没被筛过,肯定是素数
int len = cun.size();
for (int j = 0; j < len&&i*cun[j] <= mm; j++) { //<=mm 没有等于的话,错两个测试点
out[i*cun[j]] = true; //素数的倍数肯定不是素数
if (i%cun[j] == 0)break; //主要优化点,如果i是素数的倍数的话,就结束
}
}
return;
}
bool issu(int a) { //最快判断素数 用时: 842ms / 内存: 780KB
if (a == 0 || a == 1)return 0;
if (a == 2 || a == 3)return 1;
if (a % 6 != 1 && a % 6 != 5) return 0;
int qa = sqrt(a);
for (int i = 5; i <= qa; i++)
if (a%i == 0 || a % (i + 1) == 0)return 0;
return 1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, m,t;
cin >> n>>m;
//aishai(n);
for (int i = 0; i < m; i++) {
cin >> t;
if (!issu(t))
cout << "No\n";
else
cout << "Yes\n";
}
return 0;
}
费马小定理:
/*
费马小定理: 假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p) 两边都mod p;
即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
延伸:1. n*a^(p-1) ≡ n (mod p)
2. a^(p-2) ≡ a^(-1)(mod p)
正序逆序要灵活运用!
(A/B)%mod => A%mod/B => n/B => n*B^(-1) => 延伸2 => n*(B^(mod-2))%mod
*/
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
int qmi(ll a, ll b, ll mod) { //快速幂
ll flag = 1;
while (b) {
if (b & 1)flag = (flag*a) % mod;
a = (a*a) % mod;
b = b >> 1;
}
return flag%mod;
}
int main() {
int t, n, b,mod=10007;
cin >> t;
while (t--) {
cin >> n >> b;
cout << n*qmi(b, mod-2, mod) % mod << "\n";
}
return 0;
}
KMP:
#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;
const int maxn = 1e6;
string tex, pat; //tex文本串 pat模式串
int nex[maxn];
void getnext(string pat, int lenpat) { //获取nex数组
int j = nex[0] = -1; //j相当于记录nex[i]的值
for (int i = 1; i < lenpat; i++) { //求next[1]~next[len-1]
while (j != -1 && pat[i] != pat[j + 1]) {
j = nex[j]; //j回退,直到j回退到-1或pat[i]==pat[j+1]
}
if (pat[i] == pat[j+1])j++; //相等,先令j指向这个位置。
nex[i] = j; //赋值给nex[i]
}
}
int kmp(string tex, string pat) {
int lent = tex.size(), lenp = pat.size();
getnext(pat,lenp); //获取模式串的nex[]数组
int cnt = 0, j = -1; //cnt:成功匹配次数
for (int i = 0; i < lent; i++) { //试图匹配tex
// cout << "i= " << i << endl;
while (j != -1 && tex[i] != pat[j + 1]) {
j = nex[j]; //j回退,直到j回退到-1或pat[i]==pat[j+1]
}
if (tex[i] == pat[j + 1])
j++; //匹配的话,继续
if (j == lenp-1)
cout << i+2-lenp<< "\n",cnt++, j = nex[j]; //i下标从零开始的,应该属输出 i+1-(lenp)+1
}
return cnt;
}
int main() {
cin >> tex>>pat;
int lenp = pat.size();
kmp(tex, pat);
for (int i = 0; i < lenp; i++)
cout << nex[i]+1 << " ";
return 0;
}

浙公网安备 33010602011771号