我的ACAM #5 TLE,不是很懂()
查看原帖
我的ACAM #5 TLE,不是很懂()
678858
ShiRoZeTsuHL卜奎BBQ!楼主2023/9/22 14:43

不知道为什么会TLE,求大佬帮看看

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 4e5 + 5;

int n, m, dfncnt;
int suf[maxn], dfn[maxn], sze[maxn], ans[maxn];
char s[maxn];

struct edge {
    int to, nxt;
} e[maxn];

int tot = 1, head[maxn];
void addedge(int u, int v) {
    e[++tot].to = v;
    e[tot].nxt = head[u];
    head[u] = tot;
}

vector<int> ed[maxn];
struct node {
    int id, pos;
};
vector<node> ask[maxn];

struct BIT {
    int n, t[maxn];

    int lowbit(int x) { return x & (-x); }

    void add(int x, int val) {
        for(; x <= n; x += lowbit(x))
            t[x] += val;
    }

    int query(int x) {
        int res = 0;
        for(; x; x -= lowbit(x))
            res += t[x];
        return res;
    }
} bit;

struct ACAutomaton {
    int trietot;
    int ch[maxn][26], txpos[maxn], fail[maxn];
    bool vis[maxn][26];

    int insa(int now, char v, int id) {
        int x = v-'a';
        if(!ch[now][x]) {
            ch[now][x] = ++trietot;
            vis[now][x] = true;
        }
        now = ch[now][x];
        ed[now].push_back(id);
        txpos[id] = now;
        return now;
    }

    void insb(char* p, int id, int x) {
        int len = strlen(p+1), now = 0;
        for(int i = 1; i <= len; i++) {
            int v = p[i] - 'a';
            if(!ch[now][v]) {
                ch[now][v] = ++trietot;
                vis[now][v] = true;
            }
            now = ch[now][v];
        }
        ask[x].push_back((node){id, now});
    }

    void build() {
        queue<int> q;
        for(int i = 0; i < 26; i++)
            if(ch[0][i]) q.push(ch[0][i]), addedge(0, ch[0][i]);
        while(!q.empty()) {
            int u = q.front(); q.pop();
            for(int i = 0; i < 26; i++) {
                int v = ch[u][i];
                if(v) {
                    fail[v] = ch[fail[u]][i];
                    addedge(fail[v], v);
                    q.push(v);
                }
                else ch[u][i] = ch[fail[u]][i];
            }
        }
    }

    void dfs(int u) {
        dfn[u] = ++dfncnt;
        sze[u] = 1;
        for(int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            dfs(v);
            sze[u] += sze[v];
        }
    }

    void query(int u) {
        if(u && ed[u].empty()) return;
        bit.add(dfn[u], 1);
        for(int i = 0; i < ed[u].size(); i++) {
            int x = ed[u][i];
            for(int j = 0; j < ask[x].size(); j++) {
                int id = ask[x][j].id, pos = ask[x][j].pos;
                ans[id] = bit.query(dfn[pos]+sze[pos]-1) - bit.query(dfn[pos]-1);
            }
        }
        for(int i = 0; i < 26; i++)
            if(ch[u][i] && vis[u][i]) query(ch[u][i]);
        bit.add(dfn[u], -1);
    }
} ac;

int main() {
    scanf("%d", &n);
    int op, x;
    for(int i = 1; i <= n; i++) {
        scanf("%d", &op);
        if(op == 1) {
            scanf("%s", s+1);
            suf[i] = ac.insa(0, s[1], i);
        }
        else {
            scanf("%d", &x);
            scanf("%s", s+1);
            suf[i] = ac.insa(suf[x], s[1], i);
        }
    }
    scanf("%d", &m);
    for(int i = 1; i <= m; i++) {
        scanf("%d", &x);
        scanf("%s", s+1);
        ac.insb(s, i, x);
    }
    ac.build();
    ac.dfs(0);
    bit.n = dfncnt;
    ac.query(0);

//    printf("ok\n");
    for(int i = 1; i <= m; i++)
        printf("%d\n", ans[i]);
    return 0;
}
2023/9/22 14:43
加载中...