quick_sort(q, 0, n - 1);
快排
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int i = l - 1, j = r + 1, x = q[l + r >> 1];
while (i < j)
{
do i ++ ; while (q[i] < x);
do j -- ; while (q[j] > x);
if (i < j) swap(q[i], q[j]);
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
归并排序
int a[N], tmp[N];
void merge_sort(int q[], int l, int r)
{
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid), merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ];
else tmp[k ++ ] = q[j ++ ];
while (i <= mid) tmp[k ++ ] = q[i ++ ];
while (j <= r) tmp[k ++ ] = q[j ++ ];
for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}
堆排序
int n, m;
int h[N], cnt;
void down(int u)
{
int t = u;
if (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2;
if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
if (u != t)
{
swap(h[u], h[t]);
down(t);
}
}
二分
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (q[mid] >= x) r = mid;
else l = mid + 1;
}
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (q[mid] <= x) l = mid;
else r = mid - 1;
}
单链表
int head,e[N],ne[N],idx;
void init()//初始化
{
head = -1;
idx=0;
}
void add_to_head(int x)//建表
{
e[idx] = x,ne[idx]=head,head=idx++;
}
void add(int k,int x)//插入链表
{
e[idx]=x,ne[idx]=ne[k],ne[k]=idx++;
}
void remove(int k)//删除链表
{
ne[k]=ne[ne[k]];
}
双链表
// 0是左端点,1是右端点
r[0] = 1, l[1] = 0;
idx = 2;
int e[N], l[N], r[N], idx;
// 在节点a的右边插入一个数x
void insert(int a, int x)
{
e[idx] = x;
l[idx] = a, r[idx] = r[a];
l[r[a]] = idx, r[a] = idx ++ ;
}
// 删除节点a
void remove(int a)
{
l[r[a]] = l[a];
r[l[a]] = r[a];
}
KMP
int n,m;
string s,p;
cin >> n >> p + 1 >> m >> s + 1;//下标从1开始
for (int i = 2, j = 0; i <= n; i ++ )
{
while (j && p[i] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j ++ ;
ne[i] = j;
}
for (int i = 1, j = 0; i <= m; i ++ )
{
while (j && s[i] != p[j + 1]) j = ne[j];
if (s[i] == p[j + 1]) j ++ ;//当前位置匹配 继续下一位
if (j == n)//完全匹配时直接输出
{
printf("%d ", i - n);
j = ne[j];
}
}
Trie
int son[N][26], cnt[N], idx;
char str[N];
void insert(char *str)//插入
{
int p = 0;
for (int i = 0; str[i]; i ++ )
{
int u = str[i] - 'a';
if (!son[p][u]) son[p][u] = ++ idx;
p = son[p][u];
}
cnt[p] ++ ;
}
int query(char *str)//删除
{
int p = 0;
for (int i = 0; str[i]; i ++ )
{
int u = str[i] - 'a';
if (!son[p][u]) return 0;
p = son[p][u];
}
return cnt[p];
}
模拟堆
int h[N],ph[N],hp[N],cnt;
void heap_swap(int a,int b)
{
swap(ph[hp[a]],ph[hp[b]]);
swap(hp[a],hp[b]);
swap(h[a],h[b]);
}
void up(int u)
{
while(u/2&&h[u]<h[u/2]){
heap_swap(u,u/2);
u=u/2;
}
}
void down(int l)
{
int t=l;
if(l*2<=cnt&&h[l*2]<h[t]) t=l*2;
if(l*2+1<=cnt&&h[l*2+1]<h[t]) t=l*2+1;
if(l!=t){
heap_swap(l,t);
down(t);
}
}
哈希
const int N = 200003,inf=0x3f3f3f3f;
int h[N];
int find(int x)
{
int k=(x % N + N) % N;
while(h[k]!=inf && h[k] != x)
{
k++;
if(k == N) k=0;
}
return k;
}
字符串哈希
scanf("%s",str+1);//下标从1开始
P[0]=1;
for (int i = 1; i <= n; i ++ )
{
h[i] = h[i - 1] * p + str[i];
P[i] = P[i - 1] * p;
}
char str[N];
LL h[N],P[N];
LL hah(int l,int r)
{
return h[r]-h[l - 1] * P[r - l + 1];
}
dijkstra
int pa[N][N],n,m;
int vis[N];
bool st[N];
int dijkstra() // 求1号点到n号点的最短路距离
{
memset(vis, 0x3f, sizeof vis);
vis[1] = 0;
for (int i = 0; i < n; i ++ )
{
int t=-1;
for (int j = 0; j < n; j ++ )
{
if(!st[j]&&(t==-1||vis[j]<vis[t]))
t=j;
}
st[t]=true;
for(int j=1;j<=n;j++)
{
vis[j]=min(vis[j],vis[t]+pa[t][j]);
}
}
if(vis[n]==0x3f3f3f3f) return -1;
return vis[n];
}
memset(pa, 0x3f, sizeof pa);
for (int i = 0; i < m; i ++ )
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
pa[a][b] = min(pa[a][b],c);
}
Floyed
void floyd()
{
for (int k = 1; k <= n; k ++ )
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
spfa 求最短路
int n, m;
int h[N], w[N], e[N], ne[N], idx;
int dist[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
int spfa()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
queue<int> q;
q.push(1);
st[1] = true;
while (q.size())
{
int t = q.front();
q.pop();
st[t] = false;
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (dist[j] > dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
if (!st[j])
{
q.push(j);
st[j] = true;
}
}
}
}
return dist[n];
}
spfa 判断负环
int n, m;
int h[N], w[M], e[M], ne[M], idx;
int dist[N], cnt[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}
bool spfa()//找到了返回true 否则返回false
{
queue<int> q;
for (int i = 1; i <= n; i ++ )
{
st[i] = true;
q.push(i);
}
while (q.size())
{
int t = q.front();
q.pop();
st[t] = false;
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (dist[j] > dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
cnt[j] = cnt[t] + 1;
if (cnt[j] >= n) return true;
if (!st[j])
{
q.push(j);
st[j] = true;
}
}
}
}
return false;
}
Prim 最小生成树
const int N = 510, INF = 0x3f3f3f3f;
int n, m;
int g[N][N];
int dist[N];
bool st[N];
void add(int a,int b,int c)
{
g[a][b] = g[b][a] = min(g[a][b], c);
}
int prim()//最小生成树
{
memset(dist, 0x3f, sizeof dist);
int res = 0;
for (int i = 0; i < n; i ++ )
{
int t = -1;
for (int j = 1; j <= n; j ++ )
if (!st[j] && (t == -1 || dist[t] > dist[j]))
t = j;
if (i && dist[t] == INF) return INF;
if (i) res += dist[t];
st[t] = true;
for (int j = 1; j <= n; j ++ ) dist[j] = min(dist[j], g[t][j]);
}
return res;
}
快速幂
typedef long long LL;
LL qmi(int a, int b, int p)
{
LL res = 1 % p;
while (b)
{
if (b & 1) res = res * a % p;
a = a * (LL)a % p;
b >>= 1;
}
return res;
}
哈夫曼树 (优先队列)
int n,x;
priority_queue<int,vector<int>,greater<int>>q;//小根堆
void vpush(int t)//入队
{
q.push(t);
}
int Max_size() 计算最小值
{
int res=0;
while(q.size()>1)
{
int a=q.top();q.pop();
int b=q.top();q.pop();
res+=a+b;
vpush(a+b);
}
return res;
}