AC自动机+树剖TLE on 2求帮忙
查看原帖
AC自动机+树剖TLE on 2求帮忙
203453
Foofish楼主2022/8/22 19:19

RT,从双倍经验来的,但是卡了很久卡不过去,有可能是过程中的问题,样例过了。

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
template <typename T>inline void read(T& t){t=0; register char ch=getchar(); register int fflag=1;while(!('0'<=ch&&ch<='9')) {if(ch=='-') fflag=-1;ch=getchar();}while(('0'<=ch&&ch<='9')){t=t*10+ch-'0'; ch=getchar();} t*=fflag;}
template <typename T,typename... Args> inline void read(T& t, Args&... args) {read(t);read(args...);}
const int N=5e6, inf=0x3f3f3f3f;

struct BIT{
    int val[N],n;
    void intt(int _n){n=_n;}
    void update(int l,int r,int va){
        for(register int i=r+1;i<=n;i+=i&(-i)) val[i]-=va;
        for(register int i=l;i<=n;i+=i&(-i)) val[i]+=va;
    }
    int Query(int u){
        int res=0;
        for(register int i=u;i;i-=i&(-i)) res+=val[i];
        return res;
    }
};
BIT seg;

int n,m,trie[N][27],cnt,Map[N],fail[N];
string st[N];

void update(string ost,int id){
    int u=0;
    for(int i=0;i<ost.size();++i){
        if(!trie[u][ost[i]-'a']) trie[u][ost[i]-'a']=++cnt;
        u=trie[u][ost[i]-'a'];
    }
    Map[id]=u;
}
void get_fail(){
    queue<int>Q;
    for(int i=0;i<26;++i) if(trie[0][i]) Q.push(trie[0][i]);
    while(!Q.empty()){
        int u=Q.front(); Q.pop();
        for(int i=0;i<26;++i)
        if(trie[u][i]){
            fail[trie[u][i]]=trie[fail[u]][i];
            Q.push(trie[u][i]);
        }else trie[u][i]=trie[fail[u]][i];
    }
} //把 fail 树建出来
int sz[N],id[N],top[N],zr[N],dep[N],fa[N],tot;
vector<int>G[N];
void dfs(int u,int F){
    sz[u]=1; fa[u]=F; dep[u]=dep[F]+1;
    for(int v:G[u]){
        if(v==F) continue;
        dfs(v,u);
        sz[u]+=sz[v];
        zr[u]=(zr[u]==-1||sz[v]>sz[zr[u]])?v:zr[u];
    }
}
void dfs1(int u,int tp){
    top[u]=tp; id[u]=++tot;
    if(~zr[u]) dfs1(zr[u],tp);
    for(int v:G[u]){
        if(v==zr[u]||v==fa[u]) continue;
        dfs1(v,v);
    }
}
bool cmp(int x,int y){
    return id[x]<id[y];
}
void update(int x,int y,int val){
    while(top[x]!=top[y]){
        if(dep[top[x]]>dep[top[y]]) swap(x,y);
        seg.update(id[top[y]],id[y],val);
        y=fa[top[y]];
    }
    if(dep[x]>dep[y]) swap(x,y);
    seg.update(id[x],id[y],val);
}
int LCA(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]>dep[top[y]]) swap(x,y);
        y=fa[top[y]];
    }
    return (dep[x]>dep[y])?y:x;
}
int D[N];
void Query(string ost){
    int u=0,pcnt=0;
    for(int i=0;i<ost.size();++i){
        u=trie[u][ost[i]-'a'];
        D[++pcnt]=u;
    }
    sort(D+1,D+pcnt+1,cmp);
    for(int i=1;i<=pcnt;++i) update(D[i],0,1);
    for(int i=1;i<pcnt;++i) update(LCA(D[i],D[i+1]),0,-1);
}
inline void write(int x){
    if(x>=10) write(x/10);
    putchar(x+'0');
}

int main(){
    read(n,m);
    memset(zr,-1,sizeof(zr));
    for(int i=1;i<=n;++i) cin>>st[i];
    for(int i=1;i<=m;++i){
        string pst;
        cin>>pst;
        update(pst,i);
    }
    get_fail();
    for(int i=1;i<=cnt;++i) G[fail[i]].push_back(i);
    dfs(0,-1); dfs1(0,0);
    seg.intt(cnt+1);
    for(int i=1;i<=n;++i) Query(st[i]);
    for(int i=1;i<=m;++i) write(seg.Query(id[Map[i]])),putchar('\n');
    return 0;
}```
2022/8/22 19:19
加载中...