背板子

Posted riverhamster

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背板子相关的知识,希望对你有一定的参考价值。

lca转rmq

欧拉遍历,记录dep,然后建立ST表查询第一次出现位置之间的dep最小值
定义一个mindep会方便很多

const int N = 100005, E = 200005;
int to[E], nt[E], hd[N], ord[E], dep[N], fa[N], fst[N], tot = 0, Index = 0;
int st[18][E], lg[E];
void dfs(int x){
    ord[++Index] = x; fst[x] = Index;
    for(int i=hd[x]; i; i=nt[i]){
        if(to[i] == fa[x]) continue;
        fa[to[i]] = x; dep[to[i]] = dep[x] + 1;
        dfs(to[i]);
        ord[++Index] = x;
    }
}
#define mindep(x, y) (dep[x] < dep[y] ? (x) : (y))
void build_st(){
    for(int i=2; i<=Index; i<<=1) ++lg[i];
    for(int i=1; i<=Index; i++) lg[i] += lg[i-1], st[0][i] = ord[i];
    for(int i=1; i<=lg[Index]; i++)
        for(int j=1; j<=Index; j++)
            st[i][j] = j + (1 << i) - 1 > Index ? 0 : mindep(st[i-1][j], st[i-1][j + (1 << (i - 1))]);
}
int rmq(int x, int y){return mindep(st[lg[y-x+1]][x], st[lg[y-x+1]][y - (1 << lg[y-x+1]) + 1]);}
int lca(int x, int y){return fst[x] <= fst[y] ? rmq(fst[x], fst[y]) : rmq(fst[y], fst[x]);}

后缀数组,SA

sa,rk两个数组不能混,tp是第二关键字

#include <cstring>
using namespace std;
const int N = 1000005;
int chmap[128], s[N], sa[N], rk[N], tp[N], cnt[N], n, m;
void rsort(){
    for(int i=0; i<=m; i++) cnt[i] = 0;
    for(int i=1; i<=n; i++) ++cnt[rk[i]];
    for(int i=1; i<=m; i++) cnt[i] += cnt[i-1];
    for(int i=n; i>=1; i--) sa[cnt[rk[tp[i]]]--] = tp[i];
}
void getSA(){
    m = 63;
    for(int i=1; i<=n; i++) rk[i] = s[i], tp[i] = i;
    rsort();
    for(int w=1, p = 0; p < n; m = p, w <<= 1){
        p = 0;
        for(int i=1; i<=w; i++) tp[++p] = n - w + i;
        for(int i=1; i<=n; i++) if(sa[i] > w) tp[++p] = sa[i] - w;
        rsort();
        memcpy(tp, rk, sizeof tp);
        rk[sa[1]] = p = 1;
        for(int i=2; i<=n; i++)
            rk[sa[i]] = (tp[sa[i-1]] == tp[sa[i]] && (sa[i-1] + w <= n && sa[i] + w <= n && tp[sa[i-1] + w] == tp[sa[i] + w])) ? p : ++p;
    }
}

exgcd

int exgcd(int a, int b, int &x, int &y){
    if(b == 0){
        x = 1; y = 0;
        return a;
    }
    int result = exgcd(b, a%b, x, y);
    int tp = x; x = y; y = tp - a/b*y;
    return result;
}

tarjan缩点

void tarjan(int x){
    low[x] = dfn[x] = ++id;
    stk[++top] = x; instk[x] = true;
    for(int i=hd[x]; i; i=nt[i]){
        if(dfn[to[i]] == 0) tarjan(to[i]), low[x] = min(low[x], low[to[i]]);
        else if(instk[to[i]]) low[x] = min(low[x], dfn[to[i]]);
    }
    if(low[x] == dfn[x]){
        ++color; col[x] = color;
        while(stk[top] != x) instk[stk[top]] = false, col[stk[top--]] = color;
        top--; instk[x] = false;
    }
}

待补充...

以上是关于背板子的主要内容,如果未能解决你的问题,请参考以下文章

iContact卷曲子代码

创建广告时出现代码 200 和子代码 1487194 的 Facebook 错误背后的原因是啥?

SignalR OnConnected 与多台服务器和 Redis 背板

在 SpriteKit 中出现错误。 - 线程 1:EXC_BREAKPOINT(代码=1,子代码=0x1007351fc)

Facebook OAuthException代码190子代码490 - 用户注册了阻塞的登录检查点

斯威夫特 3 - 'EXC_BAD_INSTRUCTION(代码 = EXC_1386_INVOP,子代码 = 0x0)' 错误