C++算法模板|超级详细|算法选手必备!

算法模版 算法模版 算法模版

  • A u t h o r : Author: Author 缪语博

本文档基于 G P L − 3.0 L i c e n s e GPL-3.0 License GPL3.0License

本文档 G i t H u b GitHub GitHub 储存库:model

目录 目录 目录 C o n t e n t s Contents Contents

  1. 快读快写

  2. 线段树

  3. 中国剩余定理(拓展)

  4. 最短路算法

  5. LCA最近公共祖先

  6. 高精度

  7. 树链剖分

  8. 网络流

  9. KMP算法

  • 基本格式
#include <bits/stdc++.h>

using namespace std;

int main() {
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);

    return 0;
}
  • 很好用的宏定义和函数
#define ll long long 
#define N 1000010
// 二分实现
#define MID ((l + r) >> 1)
// 线段树实现
#define PII pair<int, int>
#define MAX(x, y, z) max((x), max((y), (z)))
#define PRI priority_queue
//此处注意到底是几个零
#define MOD 1000000007
#define FI first
#define SE second
#define IL inline
#define RE register
#define MINN -0x7fffffff
#define MAXX 0x7fffffff
#define HMINN -0x3f3f3f3f
#define HMAXX 0x3f3f3f3f
#define ENDL putchar('\n')

int nxt[N], head[N], to[N], to[N];
inline void add_edge(int u, int v, ll c) {
    nxt[++cnt] = head[u];
    head[u] = cnt;
    to[cnt] = v;
    w[cnt] = c;
}
// 遍历:
for(int i = head[p]; i; i = nxt[i]) {
    int v = to[i];
    // Write what you want to write.
}


inline void madd(ll &a, ll b) {
    a += b;
    a %= MOD;
}

快读快写 快读快写 快读快写

inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
inline void write(int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    if(x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
inline string stringread() {
    string str = "";
    char ch = getchar();
    while(ch == ' ' || ch == '\n' || ch == '\r') {
        ch = getchar();
    }
    while(ch != ' ' && ch != '\n' && ch != '\r') {
        str += ch;
        ch = getchar();
    } 
    return str;
}
inline void stringwrite(string str) {
    for(int i = 0; str[i] != '\0'; ++i)
        putchar(str[i]);
}

线段树 线段树 线段树

#include <bits/stdc++.h>

#define N 100010
#define ll long long
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((l + r) >> 1)

using namespace std;

int n, m;
int a[N];
ll tree[N << 2];
int siz[N << 2];
int lazy[N << 2];

void upd(int p) {
    tree[p] = tree[ls] + tree[rs];
}

void upds(int p) {
    siz[p] = siz[ls] + siz[rs];
}

void pushd(int p) {
    tree[ls] += lazy[p] * siz[ls];
    tree[rs] += lazy[p] * siz[rs];

    lazy[ls] += lazy[p];
    lazy[rs] += lazy[p];

    lazy[p] = 0;
}

void build(int p, int l, int r) {

    lazy[p] = 0;

    if(l == r)  {
        siz[p] = 1;
        tree[p] = a[l];
        return ;
    }

    build(ls, l, mid);
    build(rs, mid + 1, r);

    upd(p);
    upds(p);
}

void mdf(int p, int l, int r, int ql, int qr, int k) {
    if(ql <= l && r <= qr) {
        tree[p] += 1ll * siz[p] * k;
        lazy[p] += k;
        return;
    }
    pushd(p);
    if(ql <= mid) {
        mdf(ls, l, mid, ql, qr, k);
    }
    if(qr > mid) {
        mdf(rs, mid + 1, r, ql, qr, k);
    }
    upd(p);
}

ll qry(int p, int l, int r, int ql, int qr) {
    if(ql <= l && r <= qr) {
        return tree[p];
    }
    pushd(p);

    ll sum = 0;

    if(ql <= mid) {
        sum += qry(ls, l, mid, ql, qr);
    }
    if(qr > mid) {
        sum += qry(rs, mid + 1, r, ql, qr);
    }

    return sum;
}

int main() {

    cin >> n >> m;

    for(int i = 1; i <= n; ++i) {
        cin >> a[i];
    }

    build(1, 1, n);

    while(m--) {
        int op, x, y, k;

        cin >> op >> x >> y;

        if(op == 1) {
            cin >> k;
            mdf(1, 1, n, x, y, k);
        }
        else {
            cout << qry(1, 1, n, x, y) << endl;
        }
    }

    return 0;
}

中国剩余定理(拓展) 中国剩余定理(拓展) 中国剩余定理(拓展)

#include <bits/stdc++.h>

#define N 100010
#define ll long long

using namespace std;

ll n;
ll a[N], b[N];

ll gcd(ll a, ll b) {
    if(!b) 
        return a;
    else return gcd(b, a % b);
}

inline ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}

void merge(ll p1, ll a1, ll p2, ll a2, ll &p, ll &a) {
    p = p1 / gcd(p1, p2) * p2;
    if(p1 < p2) {
        swap(p1, p2);
        swap(a1, a2);
    }
    a = a1;
    while(a % p2 != a2)
        a += p1;
}
int main() {

    n = read();

    for(int i = 1; i <= n; ++i) {
        a[i] = read();
        b[i] = read();
        b[i] %= a[i];
    }

    for(int i = 2; i <= n; ++i) {
        merge(a[i], b[i], a[i - 1], b[i - 1], a[i], b[i]);
    }

    cout << b[n] << endl;

    return 0;
}

最短路算法 最短路算法 最短路算法

F l o y e d Floyed Floyed 算法
#include <bits/stdc++.h>
using namespace std;

int n, m;
int f[101][101];
int u, v, w;

int main() {

    cin >> n >> m;

    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= n; ++j) {
            f[i][j] = 0x3f3f3f3f;
            if(i == j) {
                f[i][j] = 0;
            }
        }
    }

    for(int i = 1; i <= m; ++i) {
        cin >> u >> v >> w;
        f[u][v] = min(f[u][v], w);
        f[v][u] = f[u][v];
    }

    for(int k = 1; k <= n; ++k)
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= n; ++j)
                f[i][j] = min(f[i][j], f[i][k] + f[k][j]);

    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= n; ++j) {
            cout << f[i][j] << ' ';
        }
        cout << endl;
    }
    return 0;
}
D i j k s t r a Dijkstra Dijkstra 算法
#include <bits/stdc++.h>
using namespace std;

int n, m, s;
struct Edge {
    int v, c;
}tmp;
vector<Edge> edges[100005];
int dis[100005];
bool vis[100005];
priority_queue<pair<int, int> , vector<pair<int, int> >, greater<pair<int, int> > > pq;

void dijkstra() {
    memset(dis, 0x3f, sizeof(dis));
    memset(vis, false, sizeof(vis));
    dis[s] = 0;
    pq.push(make_pair(0, s));

    while(!pq.empty()) {
        int u = pq.top().second;
        pq.pop();
        if(vis[u])
            continue;
        vis[u] = true;

        for(Edge e : edges[u]) {
            if(dis[e.v] > dis[u] + e.c) {
                dis[e.v] = dis[u] + e.c;
                pq.push(make_pair(dis[e.v], e.v));
            }
        }
    }
}

int main() {

    cin >> n >> m >> s;

    for(int i = 1; i <= m; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        tmp.c = w;
        tmp.v = v;
        edges[u].push_back(tmp);
    }

    dijkstra();

    for(int i = 1; i <= n; ++i)
        cout << (dis[i] == 0x3f3f3f3f ? 2147483647 : dis[i]) << ' ';
    return 0;
}
B e l l m a n − F o r d Bellman-Ford BellmanFord 算法
#include <bits/stdc++.h>

#define MAXN 100005

using namespace std;

int n, m, s;

struct Edge {
    int v;
    int c;
};

vector<Edge> edges[MAXN];
int dis[MAXN];

inline int read() {
    int x = 0, f = 1;
    char ch = 0;
    while(ch < '0' || ch > '9') {
        if(ch == '-') {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}

inline void write(int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    if(x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

void bellman_ford() {

    memset(dis, 0x3f, sizeof(dis));

    dis[s] = 0;

    bool flag;

    for(int i = 1; i <= n - 1; ++i) {
        flag = false;
        for(int u = 1; u <= n; ++u) {
            for(Edge e : edges[u]) {
                if(dis[e.v] > dis[u] + e.c) {
                    dis[e.v] = dis[u] + e.c;
                    flag = true;
                }
            }
        }
        if(!flag)
            break;
    }
}

int main() {

    n = read();
    m = read();
    s = read();

    for(int i = 1; i <= m; ++i) {
        int u, v, c;
        u = read();
        v = read();
        c = read();
        Edge tmp;
        tmp.c = c;
        tmp.v = v;
        edges[u].push_back(tmp);
    }

    bellman_ford();

    for(int i = 1; i <= n; ++i) {
        write((dis[i] == 0x3f3f3f3f ? 2147483647 : dis[i]));
        putchar(' ');
    }
    putchar('\n');
    return 0;
}

L C A LCA LCA 最近公共祖先 最近公共祖先 最近公共祖先

倍增写法: 倍增写法: 倍增写法:
#include <bits/stdc++.h>

#define N 500005
#define ll long long
#define M 31

using namespace std;

int n, m, s;
int lg[N];
int xx, yy;
vector<int> edge[N];
int dep[N];
int fa[N][M];

void add_edge(int u, int v) {
    edge[u].push_back(v);
    edge[v].push_back(u);
}

void dfs(int p, int pre) {
    fa[p][0] = pre;
    dep[p] = dep[pre] + 1;
    for(int i = 1; i <= lg[dep[p]]; ++i) {
        fa[p][i] = fa[fa[p][i - 1]][i - 1];
    }
    for(int nxt : edge[p]) {
        if(nxt != pre) {
            dfs(nxt, p);
        }
    }
}

int lca(int u, int v) {
    if(dep[u] < dep[v]) {
        swap(u, v);
    }
    while(dep[u] > dep[v]) {
        u = fa[u][lg[dep[u] - dep[v]] - 1];
    }
    if(u == v) {
        return u;
    }
    for(int llg = lg[dep[u]] - 1; llg >= 0; --llg) {
        if(fa[u][llg] != fa[v][llg]) {
            u = fa[u][llg];
            v = fa[v][llg];
        }
    }

    return fa[u][0];
}

int main() {

    cin >> n >> m >> s;

    for(int i = 1; i <= n - 1; ++i) {
        cin >> xx >> yy;
        add_edge(xx, yy);
    }

    int cntt = 0;

    for(int i = 1; i <= n; ++i) {
        if(i >= (1 << cntt)) {
            ++cntt;
            lg[i] = cntt;
        }
        else {
            lg[i] = cntt;
        }
    }

    dfs(s, 0);

    while(m--) {
        cin >> xx >> yy;
        cout << lca(xx, yy) << endl;
    }

    return 0;
}

高精度 高精度 高精度

int compare(string str1,string str2)
{
    if(str1.length()>str2.length()) return 1;
    else if(str1.length()<str2.length())  return -1;
    else return str1.compare(str2);
}

//高精度加法
//只能是两个正数相加
string add(string str1,string str2)
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    //前面补0,弄成长度相同
    if(len1<len2)
    {
        for(int i=1;i<=len2-len1;i++)
           str1="0"+str1;
    }
    else
    {
        for(int i=1;i<=len1-len2;i++)
           str2="0"+str2;
    }
    len1=str1.length();
    int cf=0;
    int temp;
    for(int i=len1-1;i>=0;i--)
    {
        temp=str1[i]-'0'+str2[i]-'0'+cf;
        cf=temp/10;
        temp%=10;
        str=char(temp+'0')+str;
    }
    if(cf!=0)  str=char(cf+'0')+str;
    return str;
}

//高精度减法
//只能是两个正数相减,而且要大减小
string sub(string str1,string str2)
{
    string str;
    int tmp=str1.length()-str2.length();
    int cf=0;
    for(int i=str2.length()-1;i>=0;i--)
    {
        if(str1[tmp+i]<str2[i]+cf)
        {
            str=char(str1[tmp+i]-str2[i]-cf+'0'+10)+str;
            cf=1;
        }
        else
        {
            str=char(str1[tmp+i]-str2[i]-cf+'0')+str;
            cf=0;
        }
    }
    for(int i=tmp-1;i>=0;i--)
    {
        if(str1[i]-cf>='0')
        {
            str=char(str1[i]-cf)+str;
            cf=0;
        }
        else
        {
            str=char(str1[i]-cf+10)+str;
            cf=1;
        }
    }
    str.erase(0,str.find_first_not_of('0'));//去除结果中多余的前导0
    return str;
}

//高精度乘法
//只能是两个正数相乘
string mul(string str1,string str2)
{
    string str;
    int len1=str1.length();
    int len2=str2.length();
    string tempstr;
    for(int i=len2-1;i>=0;i--)
    {
        tempstr="";
        int temp=str2[i]-'0';
        int t=0;
        int cf=0;
        if(temp!=0)
        {
            for(int j=1;j<=len2-1-i;j++)
              tempstr+="0";
            for(int j=len1-1;j>=0;j--)
            {
                t=(temp*(str1[j]-'0')+cf)%10;
                cf=(temp*(str1[j]-'0')+cf)/10;
                tempstr=char(t+'0')+tempstr;
            }
            if(cf!=0) tempstr=char(cf+'0')+tempstr;
        }
        str=add(str,tempstr);
    }
    str.erase(0,str.find_first_not_of('0'));
    return str;
}

//高精度除法
//两个正数相除,商为quotient,余数为residue
//需要高精度减法和乘法
void div(string str1,string str2,string &quotient,string &residue)
{
    quotient=residue="";//清空
    if(str2=="0")//判断除数是否为0
    {
        quotient=residue="ERROR";
        return;
    }
    if(str1=="0")//判断被除数是否为0
    {
        quotient=residue="0";
        return;
    }
    int res=compare(str1,str2);
    if(res<0)
    {
        quotient="0";
        residue=str1;
        return;
    }
    else if(res==0)
    {
        quotient="1";
        residue="0";
        return;
    }
    else
    {
        int len1=str1.length();
        int len2=str2.length();
        string tempstr;
        tempstr.append(str1,0,len2-1);
        for(int i=len2-1;i<len1;i++)
        {
            tempstr=tempstr+str1[i];
            tempstr.erase(0,tempstr.find_first_not_of('0'));
            if(tempstr.empty())
              tempstr="0";
            for(char ch='9';ch>='0';ch--)//试商
            {
                string str,tmp;
                str=str+ch;
                tmp=mul(str2,str);
                if(compare(tmp,tempstr)<=0)//试商成功
                {
                    quotient=quotient+ch;
                    tempstr=sub(tempstr,tmp);
                    break;
                }
            }
        }
        residue=tempstr;
    }
    quotient.erase(0,quotient.find_first_not_of('0'));
    if(quotient.empty()) quotient="0";
}

树链剖分 树链剖分 树链剖分

#include <bits/stdc++.h>

#define N 200010
#define ENDL putchar('\n')

#define mid ((l + r) >> 1)
#define ls (p << 1)
#define rs (p << 1 | 1)

using namespace std;

int n, m, r, MOD;
int nxt[N], head[N], to[N], w[N];
int top[N];
int si[N], fa[N], id[N], son[N], wt[N], dep[N];
int cnt = 0, e = 0;
int tree[N << 2], siz[N << 2], lazy[N << 2];

inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}

inline void write(int x) {
    if(x < 0) {
        putchar('-');
        x = -x;
    }
    if(x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}


inline void add(int &a, int b) {
    a = (a + b) % MOD;
}


inline void upd(int p) {
    tree[p] = (tree[ls] + tree[rs]) % MOD;
}

inline void upds(int p) {
    siz[p] = siz[ls] + siz[rs];
}

inline void pushd(int p) {
    if(!lazy[p])
        return;

    add(tree[ls], siz[ls] * lazy[p] % MOD);
    add(tree[rs], siz[rs] * lazy[p] % MOD);

    add(lazy[ls], lazy[p]);
    add(lazy[rs], lazy[p]);

    lazy[p] = 0;
}

inline void build(int p, int l, int r) {
    if(l == r) {
        tree[p] = wt[l];
        siz[p] = 1;
        lazy[p] = 0;
        return;
    }
    build(ls, l, mid);
    build(rs, mid + 1, r);
    upd(p);
    upds(p);
}

inline void mdf(int p, int l, int r, int ql, int qr, int x) {
    if(ql <= l && r <= qr) {
        add(tree[p], siz[p] * x % MOD);
        add(lazy[p], x);
        return;
    }
    pushd(p);
    if(ql <= mid) {
        mdf(ls, l, mid, ql, qr, x);
    }
    if(qr > mid) {
        mdf(rs, mid + 1, r, ql, qr, x);
    }
    upd(p);
}

inline int qry(int p, int l, int r, int ql, int qr) {
    if(ql <= l && r <= qr) {
        return tree[p];
    }
    pushd(p);
    int sum = 0;
    if(ql <= mid) {
        add(sum, qry(ls, l, mid, ql, qr));
    }
    if(qr > mid) {
        add(sum, qry(rs, mid + 1, r, ql, qr));
    }
    return sum;
}


inline void add_edge(int u, int v) {
    nxt[++e] = head[u];
    head[u] = e;
    to[e] = v;
}

inline void dfs1(int p, int pre, int depth) {
    dep[p] = depth;
    fa[p] = pre;
    si[p] = 1;
    int maxx = -1;

    for(int i = head[p]; i; i = nxt[i]) {
        int v = to[i];
        if(v != pre) {
            dfs1(v, p, depth + 1);
            si[p] +=  si[v];
            if(si[v] > maxx) {
                maxx = si[v];
                son[p] = v;
            }
        }
    }
}

inline void dfs2(int p, int topp) {
    id[p] = ++cnt;
    wt[cnt] = w[p];
    top[p] = topp;
    if(!son[p])
        return;
    dfs2(son[p], topp);
    for(int i = head[p]; i; i = nxt[i]) {
        int v = to[i];
        if(v != son[p] && v != fa[p]) {
            dfs2(v, v);
        }
    }
}


inline void modify1(int l, int r, int x) {
    x %= MOD;
    while(top[l] != top[r]) {
        if(dep[top[l]] < dep[top[r]]) {
            swap(l, r);
        }
        mdf(1, 1, n, id[top[l]], id[l], x);
        l = fa[top[l]];
    }
    if(dep[l] > dep[r])
        swap(l, r);
    mdf(1, 1, n, id[l], id[r], x);
}

inline int query1(int l, int r) {
    int sum = 0;
    while(top[l] != top[r]) {
        if(dep[top[l]] < dep[top[r]]) {
            swap(l, r);
        }
        add(sum, qry(1, 1, n, id[top[l]], id[l]));
        l = fa[top[l]];
    }
    if(dep[l] > dep[r])
        swap(l, r);
    add(sum, qry(1, 1, n, id[l], id[r]));
    return sum;
}

inline void modify2(int p, int x) {
    mdf(1, 1, n, id[p], id[p] + si[p] - 1, x);
}

inline int query2(int p) {
    return qry(1, 1, n, id[p], id[p] + si[p] - 1) % MOD;
}

int main() {

    n = read();
    m = read();
    r = read();
    MOD = read();

    for(int i = 1; i <= n; ++i) {
        w[i] = read();
    }

    for(int i = 1; i <= n - 1; ++i) {
        int u, v;
        u = read();
        v = read();
        add_edge(u, v);
        add_edge(v, u);
    }

    dfs1(r, 0, 1);
    dfs2(r, r);

    build(1, 1, n);

    while(m--) {
        int op;
        op = read();
        if(op == 1) {
            int x, y, z;
            x = read();
            y = read();
            z = read();
            modify1(x, y, z);
        }
        else if(op == 2) {
            int x, y;
            x = read();
            y = read();
            write(query1(x, y));
            ENDL;
        }
        else if(op == 3) {
            int x, z;
            x = read();
            z = read();
            modify2(x, z);
        }
        else {
            int x;
            x = read();
            write(query2(x));
            ENDL;
        }
    }

    return 0;
}

网络流 网络流 网络流

D i n i c Dinic Dinic 最大流
#include <bits/stdc++.h>

#define N 500010

using namespace std;

long long nxt[N], to[N], head[N], w[N];
long long now[N];
int d[N];
long long n, m, s, t;
long long cnt = 1;

inline void add(int u, int v, long long c) {
    nxt[++cnt] = head[u];
    head[u] = cnt;
    to[cnt] = v;
    w[cnt] = c;

    nxt[++cnt] = head[v];
    head[v] = cnt;
    to[cnt] = u;
    w[cnt] = 0;
}

inline bool bfs() {
    queue<int> q;
    q.push(s);
    memset(d, 0x3f, sizeof(d));
    d[s] = 0;
    now[s] = head[s];
    while(!q.empty()) {
        int x = q.front();
        q.pop();
        for(int i = head[x]; i; i = nxt[i]) {
            int v = to[i];
            if(d[v] == 0x3f3f3f3f && w[i] > 0) {
                d[v] = d[x] + 1;
                now[v] = head[v];
                q.push(v);
                if(v == t) {
                    return 1;
                }
            }
        }
    }
    return 0;
}

inline long long dfs(int x, long long flow) {
    if(x == t) {
        return flow;
    }
    long long k;
    for(int i = now[x]; i; i = nxt[i]) {
        now[x] = i;
        int v = to[i];
        if(d[v] != d[x] + 1 || w[i] <= 0) {
            continue;
        }
        k = dfs(v, min(flow, w[i]));
        if(k) {
            w[i] -= k;
            w[i ^ 1] += k;
            return k;
        }
        else {
            d[v] = 0x3f3f3f3f;
        }
    }
    return 0;
}

inline long long dinic() {
    long long sum = 0;
    while(bfs()) {
        sum += dfs(s, 0x7fffffff);
    }
    return sum;
}

int main() {

    cin >> n >> m >> s >> t;

    while(m--) {
        long long u, v, c;
        cin >> u >> v >> c;
        add(u, v, c);
    }

    cout << dinic() << endl;

    return 0;
}

K M P KMP KMP 算法 算法 算法

#include <bits/stdc++.h>

#define N 1000001

using namespace std;

char s1[N], s2[N];
int la, lb;
int j = 0;
int kmp[N];

int main() {
    cin >> s1 + 1;
    cin >> s2 + 1;

    la = strlen(s1 + 1);
    lb = strlen(s2 + 1);

    for(int i = 1; i <= lb; ++i) {
        while(j && s2[i + 1] != s2[j + 1]) {
            j = kmp[j];
        }
        if(s2[i + 1] == s2[j + 1]) {
            ++j;
            kmp[i + 1] = j;
        }
    }

    j = 0;

    for(int i = 1; i <= la; ++i) {
        while(j && s1[i] != s2[j + 1]) {
            j = kmp[j];
        }
        if(s1[i] == s2[j + 1]) {
            ++j;
        }
        if(j == lb) {
            cout << i - lb + 1 << endl;
            j = kmp[j];
        }
    }

    for(int i = 1; i <= lb; ++i) {
        cout << kmp[i] << ' ';
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值