10pts 求 hack
查看原帖
10pts 求 hack
655192
Tibrella楼主2023/6/12 16:47

如题,除了 #1 全 WA,自己写了好几个数据都没啥问题...

思路:fail 树+树状数组,离线询问,dfs,与第一篇题解相同。

这题应该不能 trie 图吧...我反正没建

另外处理过连续两个 P 的问题了

#include <iostream>
#include <list>
#include <queue>
#include <string>

using std::cin;
using std::cout;
using std::string;
using i32 = int;

#define N 100006

string s, t;
i32 n;

struct Node {
    i32 son[26], fail;
    i32 cnt;
    i32 fa;
    std::list<i32> id, fail_son;
} trie[N << 1];
i32 tot = 1, idx = 1;
i32 tail[N], tt;

void insert(char c) {
    c -= 'a';
    if (!trie[idx].son[c]) trie[idx].son[c] = ++tot;
    trie[trie[idx].son[c]].fa = idx;
    idx = trie[idx].son[c];
}

void back() {
    idx = trie[idx].fa;
}

void end() {
    ++trie[idx].cnt;
    tail[++tt] = idx;
    trie[idx].id.emplace_back(tt);
}

void build() {
    std::queue<i32> q;
    for (i32 i = 0; i < 26; ++i)
        if (trie[1].son[i]) {
            trie[trie[1].son[i]].fail = 1;
            q.push(trie[1].son[i]);
        }
    while (!q.empty()) {
        i32 nod = q.front(), lfail = trie[q.front()].fail;
        q.pop();
        trie[lfail].fail_son.emplace_back(nod);
        for (i32 i = 0; i < 26; ++i) {
            i32& to = trie[nod].son[i];
            if (to) {
                if (trie[lfail].son[i])
                    trie[to].fail = trie[lfail].son[i];
                else
                    trie[to].fail = 1;
                q.push(to);
            } else
                to = 0;
        }
    }
}

i32 dfn[N], qdfn[N], siz[N], tim;
void dfs(i32 nod) {
    dfn[nod] = ++tim;
    qdfn[tim] = nod;
    siz[nod] = 1;
    for (auto& to : trie[nod].fail_son) {
        if (!dfn[to]) {
            dfs(to);
            siz[nod] += siz[to];
        }
    }
}

i32 tree[N];
i32 lowbit(i32 x) {
    return x & (-x);
}
void modify(i32 pos, i32 v) {
    // if (!pos) return;
    for (; pos <= tim; pos += lowbit(pos))
        tree[pos] += v;
}
i32 que(i32 pos) {
    // if (pos < 0) return 0;
    i32 res = 0;
    for (; pos; pos -= lowbit(pos))
        res += tree[pos];
    return res;
}
i32 query(i32 nod) {
    // cout << dfn[nod] << ' ' << dfn[nod] + siz[nod] - 1 << '\n';
    return que(dfn[nod] + siz[nod] - 1) - que(dfn[nod] - 1);
}

struct qu {
    i32 sid, aid;
};

std::list<qu> q[N];
i32 ans[N];

void answer(i32 nod) {
    modify(dfn[nod], 1);
    // cout << nod << ' ' << trie[nod].cnt << '\n';
    if (trie[nod].cnt) {
        for (auto& id : trie[nod].id)
            for (auto& r : q[id]) {
                ans[r.aid] = query(tail[r.sid]);
                // cout << r.aid << ' ' << r.sid << ' ' << ans[r.aid] << '\n';
            }
    }
    for (i32 i = 0; i < 26; ++i) {
        if (trie[nod].son[i]) answer(trie[nod].son[i]);
    }
    modify(dfn[nod], -1);
}

int main() {
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> t;
    i32 siz = 0;
    for (auto& c : t) {
        if (c == 'P' && siz) {
            end();
        } else if (c == 'B') {
            back();
        } else {
            insert(c);
            ++siz;
        }
    }

    build();

    i32 m;
    cin >> m;
    i32 x, y;
    for (int i = 1; i <= m; ++i) {
        cin >> x >> y;
        // cout << x << ' ' << y << ' ' << i << '\n';
        q[y].emplace_back((qu){ x, i });
    }
    dfs(1);
    answer(1);
    for (int i = 1; i <= m; ++i)
        cout << ans[i] << '\n';

    // for (int i = 1; i <= tot; ++i) {
    // for (auto& x : trie[i].fail_son)
    //     cout << (i32)x << ' ';
    // cout << '\n';
    // cout << trie[i].cnt << ' ';
    // }

    // cout << tim;

    return 0;
}
2023/6/12 16:47
加载中...