zoukankan      html  css  js  c++  java
  • [Coci2015]Divljak

    题目大意:

    Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的。
    接下来会发生q个操作,操作有两种形式:
    “1 P”,Bob往自己的集合里添加了一个字符串P。
    “2 x”,Alice询问Bob,集合T中有多少个字符串包含串S_x。(我们称串A包含串B,当且仅当B是A的子串)
    Bob遇到了困难,需要你的帮助。
    题解:
    建出fail树然后搞树链的并……
    恶心
    正经的题解开始。
    先建出关于S的trie树,把fail树建出来。
    然后每读进来一个T,就把它放在trie树上走一边,然后把经过的点记录下来。
    按dfs入栈序排序。
    然后在dfs序上将每个点入栈时间打+1标记,将相邻点的lca打-1标记
    查询时直接tout-tin即可。
    代码:
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    #define M 2000050
    int n,q,tot,tl[N];
    char ch[M];
    struct Trie
    {
        int ch[28],fl;
    }tr[M];
    int hed[M],cnt;
    struct EG
    {
        int to,nxt;
    }e[M];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    void trie_pic()
    {
        queue<int>q;
        for(int i=1;i<=26;i++)
            if(tr[0].ch[i])
            {
                q.push(tr[0].ch[i]);
                ae(0,tr[0].ch[i]);
            }
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int i=1;i<=26;i++)
            {
                int &v = tr[u].ch[i];
                if(!v)
                {
                    v = tr[tr[u].fl].ch[i];
                    continue;
                }
                tr[v].fl = tr[tr[u].fl].ch[i];
                ae(tr[v].fl,v);
                q.push(v);
            }
        }
    }
    int tin[M],tout[M],tim,fa[M],son[M],siz[M],dep[M],top[M];
    void dfs(int u)
    {
        tin[u]=++tim;
        siz[u]=1;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            fa[to]=u;
            dep[to]=dep[u]+1;
            dfs(to);
            siz[u]+=siz[to];
            if(siz[to]>siz[son[u]]||!son[u])son[u]=to;
        }
        tout[u]=tim;
    }
    void dfs2(int u,int Top)
    {
        top[u]=Top;
        if(!son[u])return ;
        dfs2(son[u],Top);
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(to!=son[u])dfs2(to,to);
        }
    }
    int get_lca(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            x=fa[top[x]];
        }
        return dep[x]<dep[y]?x:y;
    }
    int f[M];
    void up(int x,int d)
    {
        if(!x)return ;
        while(x<=2000000)f[x]+=d,x+=(x&(-x));
    }
    int down(int x)
    {
        if(!x)return 0;
        int ret = 0;
        while(x)ret+=f[x],x-=(x&(-x));
        return ret;
    }
    int sta[M],tal;
    bool cmp(int x,int y)
    {
        return tin[x]<tin[y];
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ch+1);
            int len = strlen(ch+1),u=0;
            for(int j=1;j<=len;j++)
            {
                int c = ch[j]-'a'+1;
                if(!tr[u].ch[c])tr[u].ch[c]=++tot;
                u=tr[u].ch[c];
            }
            tl[i]=u;
        }
        trie_pic();
        dfs(0);dfs2(0,0);
        scanf("%d",&q);
        for(int opt,x,i=1;i<=q;i++)
        {
            scanf("%d",&opt);
            if(opt==1)
            {
                scanf("%s",ch+1);
                tal=0;
                int len = strlen(ch+1),u=0;
                for(int j=1;j<=len;j++)
                {
                    u = tr[u].ch[ch[j]-'a'+1];
                    sta[++tal]=u;
                }
                sort(sta+1,sta+1+tal,cmp);
                for(int i=1;i<=tal;i++)up(tin[sta[i]],1);
                for(int i=1;i<tal;i++)up(tin[get_lca(sta[i],sta[i+1])],-1);
            }else
            {
                scanf("%d",&x);
                printf("%d
    ",down(tout[tl[x]])-down(tin[tl[x]]-1));
            }
        }
        return 0;
    }
  • 相关阅读:
    算法训练 P1103
    算法训练 表达式计算
    算法训练 表达式计算
    基础练习 时间转换
    基础练习 字符串对比
    Codeforces 527D Clique Problem
    Codeforces 527C Glass Carving
    Codeforces 527B Error Correct System
    Codeforces 527A Glass Carving
    Topcoder SRM 655 DIV1 250 CountryGroupHard
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10017401.html
Copyright © 2011-2022 走看看