退役划水二 诈尸记录(春季赛前打打板子)
图论
存图
链式前向星
$Code$
struct Graph{
int cnt;
int head[MAXN];
Graph(){
cnt = 0;
memset(head, 0, sizeof(head));
}
struct Edge{
int to, next, dis;
}e[MAXN];
inline void Add(int u, int v, int w){
e[++cnt].to = v;
e[cnt].dis = w;
e[cnt].next = head[u];
head[u] = cnt;
}
}G;
最短路
\(\mathit{Floyed}\)
$Code$
void Floyed(){
for(register int k = 1; k <= n; k++){
for(register int i = 1; i <= n; i++){
for(register int j = 1; j <= n; j++){
if(k == i || k == j || i == j) continue;
if(map[i][j] > map[i][k] + map[k][j]) map[i][j] = map[i][k] + map[k][j];
}
}
}
}
\(\mathit{SPFA}\)
$Code$
void Spfa(int u){
queue<int> q;
memset(dis, 0x3f, sizeof(dis));
q.push(u), dis[u] = 0, vis[u] = true;
while(!q.empty()){
int t = q.front();
for(register int i = G.head[t]; i; i = G.e[i].next){
int v = G.e[i].to;
if(dis[v] > dis[t] + G.e[i].dis){
dis[v] = dis[t] + G.e[i].dis;
if(!vis[v]) q.push(v), vis[v] = true;
}
}
vis[t] = false;
q.pop();
}
}
堆优化 \(\mathit{Dijkstra}\)
$Code$
struct Road{
int pos, dis;
bool operator < (const Road &a) const{
return dis > a.dis;
}
};
priority_queue< Road, vector<Road>, greater<Road> > q;
void Dijkstra(int u){
memset(dis, 0x3f, sizeof(dis));
dis[u] = 0, q.push((Road){u, 0});
while(!q.empty()){
int t = q.top().pos;
q.pop();
if(vis[t]) continue;
vis[t] = true;
for(register int i = G.head[t]; i; i = G.e[i].next){
int v = G.e[i].to;
if(dis[v] > dis[t] + G.e[i].dis){
dis[v] = dis[t] + G.e[i].dis;
if(!vis[v]) q.push((Road){v, dis[v]});
}
}
}
}
最小生成树
\(\mathit{Prim}\) 算法
$Code$
struct Road{
int pos, dis;
bool operator < (const Road &a) const{
return dis > a.dis;
}
};
priority_queue< Road, vector<Road>, greater<Road> > q;
void Prim(){
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0;
q.push((Road){1, dis[1]});
while(!q.empty() && tot < n){
int k = q.top().pos;
q.pop();
if(used[k]) continue;
tot++;
sum += dis[k];
used[k] = true;
for(register int i = head[k]; i; i = e[i].next){
int v = e[i].to;
if(dis[v] > e[i].dis){
dis[v] = e[i].dis;
q.push((Road){v, dis[v]});
}
}
}
}
\(\mathit{Kruskal}\) 算法
$Code$
struct Line{
int from, to, dis;
}line[MAXM];
bool cmp(const Line &a, const Line &b){
return a.dis < b.dis;
}
struct Union_Set{
int fa[MAXN];
void init(int n){
for(register int i = 1; i <= n; i++) fa[i] = i;
}
int Find(int x){
return fa[x] == x ? x : fa[x] = Find(fa[x]);
}
}U;
void Kruskal(){
U.init(n);
sort(line + 1, line + 1 + m, cmp);
for(register int i = 1; i <= m; i++){
int u = line[i].from, v = line[i].to;
int fa_u = U.Find(u), fa_v = U.Find(v);
if(fa_u != fa_v){
++tot;
U.fa[fa_u] = fa_v;
G.Add(u, v, line[i].dis), G.Add(v, u, line[i].dis);
}
if(tot == n - 1) break;
}
}
\(\mathit{Tarjan}\)
求强连通分量及缩点
$Code$
void Tarjan(int u){
low[u] = dfn[u] = ++num;
vis[u] = true;
stk[++top] = u;
for(register int i = G.head[u]; i; i = G.e[i].next){
int v = G.e[i].to;
if(!dfn[v]){
Tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[v]){
++tot; int t;
do{
t = stk[top--];
vis[t] = false;
belong[t] = tot;
}while(t != u);
}
}
void Rebuild(){
G.cnt = 0;
memset(G.head, 0, sizeof(G.head));
for(register int i = 1; i <= m; i++){
int u = from[i], v = to[i];
if(belong[u] != belong[v]) G.Add(u, v);
}
}
求割点
$Code$
void Tarjan(int u){
dfn[u] = low[u] = ++num;
int son = 0;
for(register int i = G.head[u]; i; i = G.e[i].next){
int v = G.e[i].to;
if(!dfn[v]){
++son;
Tarjan(v);
low[u] = min(low[u], low[v]);
if(dfn[u] <= low[v]){
if(son > 1 || u != root) cut[u] = true;
}
}
else low[u] = min(low[u], dfn[v]);
}
}
求点双联通分量
$Code$
void Tarjan(int u, int fa){
dfn[u] = low[u] = ++num;
vis[u] = true, stk[++top] = u;
int son = 0; bool first = true;
for(register int i = G.head[u]; i; i = G.e[i].next){
int v = G.e[i].to;
if(first && v == fa){
first = false;
continue;
}
if(!dfn[v]){
++son;
Tarjan(v, u);
low[u] = min(low[u], low[v]);
if(dfn[u] <= low[v]){
cut[u] = true;
++tot;
point[tot].push_back(u);
int t;
do{
t = stk[top--];
point[tot].push_back(u);
}while(t != u);
}
}
else low[u] = min(low[u], dfn[v]);
}
if(!fa && son == 1) cut[u] = false;
}
二分图
匈牙利算法
$Code$
bool dfs(int u){
for(register int i = G.head[u]; i; i = G.e[i].next){
int v = G.e[i].to;
if(!vis[v]){
vis[v] = true;
if(!match[v] || dfs(match[v])){
match[v] = u;
return true;
}
}
}
return false;
}
int Hungary(){
int ans = 0;
for(register int i = 1; i <= n; i++){
memset(vis, 0, sizeof(vis));
if(dfs(i)) ++ans;
}
return ans;
}
\(\mathit{Kruskal}\) 重构树
$Code$
struct Line{
int from, to, dis;
}line[MAXM];
bool cmp(const Line &a, const Line &b){
return a.dis < b.dis;
}
struct Union_Set{
int fa[MAXN];
void init(int n){
for(register int i = 1; i <= n; i++) fa[i] = i;
}
int Find(int x){
return fa[x] == x ? x : fa[x] = Find(fa[x]);
}
}U;
void Kruskal(){
int tot = 0; sum = n, G.cnt = 0;
memset(G.head, 0, sizeof(G.head));
U.init(n << 1);
sort(line + 1, line + 1 + m, cmp);
for(register int i = 1; i <= m; i++){
int u = line[i].from, v = line[i].to;
int fa_u = U.Find(u), fa_v = U.Find(v);
if(fa_u != fa_v){
++tot;
val[++sum] = line[i].dis;
G.Add(fa_u, sum), G.Add(sum, fa_u);
G.Add(fa_v, sum), G.Add(sum, fa_v);
U.fa[fa_u] = U.fa[fa_v] = sum;
}
if(tot == n - 1) break;
}
}
字符串
哈希
不用写。
\(\mathit{KMP}\) 算法
不会真有人到退役也搞不清楚 \(KMP\) 吧,不会吧不会吧。😋
\(\mathit{Trie}\) 树
字典树
$Code$
struct Trie{
int sz;
bool val[MAXN];
int ch[MAXN][SIZE];
Trie(){
sz = 0;
memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val));
}
void Insert(char *s){
int u = 0, len = strlen(s + 1);
for(register int i = 1; i <= len; i++){
int v = s[i] - 'a';
if(!ch[u][v]) ch[u][v] = ++sz;
u = ch[u][v];
}
val[u] = true;
}
bool Search(char *s){
int u = 0, len = strlen(s + 1);
for(register int i = 1; i <= len; i++){
int v = s[i] - 'a';
if(!ch[u][v]) return false;
u = ch[u][v];
}
if(val[u]) return true;
else return false;
}
}T;
\(01Trie\)
$Code$
struct Trie{
int sz;
bool val[MAXN];
int ch[MAXN][2];
Trie(){
sz = 0;
memset(ch, 0, sizeof(ch));
memset(val, 0, sizeof(val));
}
void Insert(int num){
int u = 0;
for(register int i = 31; i >= 0; i--){
int v = (num >> i) & 1;
if(!ch[u][v]) ch[u][v] = ++sz;
u = ch[u][v];
}
val[u] = true;
}
int Search(int num){
int u = 0, ans = 0;
for(register int i = 31; i >= 0; i--){
int v = (num >> i) & 1;
if(ch[u][v ^ 1]) ans += 1 << i, u = ch[u][v ^ 1];
else u = ch[u][v];
}
return ans;
}
}T;
\(\mathit{AC}\) 自动机
树论
树链剖分
$Code$
struct Graph{
int cnt;
int head[MAXN];
struct Edge{
int to, next;
}e[MAXN << 1];
void Add(int u, int v){
e[++cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}
}G;
void dfs_deep(int rt, int father, int depth){
size[rt] = 1, fa[rt] = father, deep[rt] = depth;
int max_son = -1;
for(register int i = G.head[rt]; i; i = G.e[i].next){
int v = G.e[i].to;
if(v == father) continue;
dfs_deep(v, rt, depth + 1);
size[rt] += size[v];
if(size[v] > max_son) son[rt] = v, max_son = size[v];
}
}
void dfs_top(int rt, int top_fa){
dfn[rt] = ++num, top[rt] = top_fa, val[num] = data[rt];
if(!son[rt]) return;
dfs_top(son[rt], top_fa);
for(register int i = G.head[rt]; i; i = G.e[i].next){
int v = G.e[i].to;
if(!dfn[v]) dfs_top(v, v);
}
}
struct Segment_Tree{
struct Tree{
int l, r;
LL sum;
LL lazy;
}tr[MAXN << 2];
inline int lson(int rt){
return rt << 1;
}
inline int rson(int rt){
return rt << 1 | 1;
}
inline void Pushup(int rt){
tr[rt].sum = 1LL * (tr[lson(rt)].sum + tr[rson(rt)].sum) % p;
}
void Build(int rt, int l, int r){
tr[rt].l = l, tr[rt].r = r;
if(l == r){
tr[rt].sum = val[l] % p;
return;
}
int mid = (l + r) >> 1;
Build(lson(rt), l, mid);
Build(rson(rt), mid + 1, r);
Pushup(rt);
}
inline void Pushdown(int rt){
if(tr[rt].lazy){
tr[lson(rt)].lazy = 1LL * (tr[lson(rt)].lazy + tr[rt].lazy) % p;
tr[rson(rt)].lazy = 1LL * (tr[rson(rt)].lazy + tr[rt].lazy) % p;
tr[lson(rt)].sum = 1LL * (tr[lson(rt)].sum + (tr[lson(rt)].r - tr[lson(rt)].l + 1) % p * tr[rt].lazy % p) % p;
tr[rson(rt)].sum = 1LL * (tr[rson(rt)].sum + (tr[rson(rt)].r - tr[rson(rt)].l + 1) % p * tr[rt].lazy % p) % p;
tr[rt].lazy = 0;
}
}
void Update_Add(int rt, int l, int r, int data){
if(tr[rt].l >= l && tr[rt].r <= r){
tr[rt].lazy = 1LL * (tr[rt].lazy + data) % p;
tr[rt].sum = 1LL * (tr[rt].sum + (tr[rt].r - tr[rt].l + 1) % p * data % p) % p;
return;
}
Pushdown(rt);
int mid = (tr[rt].l + tr[rt].r) >> 1;
if(l <= mid) Update_Add(lson(rt), l, r, data);
if(r > mid) Update_Add(rson(rt), l, r, data);
Pushup(rt);
}
LL Query_Sum(int rt, int l, int r){
if(tr[rt].l >= l && tr[rt].r <= r) return tr[rt].sum;
Pushdown(rt);
LL ans = 0;
int mid = (tr[rt].l + tr[rt].r) >> 1;
if(l <= mid) ans = 1LL * (ans + Query_Sum(lson(rt), l, r)) % p;
if(r > mid) ans = 1LL * (ans + Query_Sum(rson(rt), l, r)) % p;
return ans;
}
}S;
void Update_Tree_Add(int x, int y, int data){
while(top[x] != top[y]){
if(deep[top[x]] < deep[top[y]]) swap(x, y);
S.Update_Add(1, dfn[top[x]], dfn[x], data);
x = fa[top[x]];
}
if(deep[x] > deep[y]) swap(x, y);
S.Update_Add(1, dfn[x], dfn[y], data);
}
LL Query_Tree_Sum(int x, int y){
LL ans = 0;
while(top[x] != top[y]){
if(deep[top[x]] < deep[top[y]]) swap(x, y);
ans = 1LL * (ans + S.Query_Sum(1, dfn[top[x]], dfn[x])) % p;
x = fa[top[x]];
}
if(deep[x] > deep[y]) swap(x, y);
ans = 1LL * (ans + S.Query_Sum(1, dfn[x], dfn[y])) % p;
return ans;
}
以下为博客签名,与博文无关。
只要你们不停下来,那前面就一定有我。所以啊,不要停下来~
本文来自博客园,作者:TSTYFST,转载请注明原文链接:https://www.cnblogs.com/TSTYFST/p/17139035.html