• Spoj8093 Sevenk Love Oimaster


    题目描述

    题解:

    对于所有n串建广义后缀自动机。

    (广义后缀自动机唯一区别就是每次将las附成1,并不需要在插入时特判)

    建完后再建出parent树,然后用dfs序+树状数组搞区间不同种类。

    其实就是HH的项链+广义后缀自动机。很水的。(虽然我调了半个晚上)

    代码:

    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    int n,q;
    char s[360050];
    int ic(char c)
    {
        if(c>='a'&&c<='z')return c-'a'+1;
        if(c>='A'&&c<='Z')return c-'A'+27;
        if(c>='0'&&c<='9')return c-'0'+53;
        if(c==',')return 63;
        if(c=='.')return 64;
        return 65;
    }
    int tin[2*N],tout[2*N],tim,pla[2*N];
    struct SAM
    {
        struct node
        {
            int len,pre,trs[68];
            vector<int>v;
        }p[2*N];
        int tot,las;
        SAM(){tot=las=1;}
        void res(){las=1;}
        void insert(int c,int k)
        {
            int np,nq,lp,lq;
            np = ++tot;
            p[np].len = p[las].len+1;
            for(lp=las;lp&&!p[lp].trs[c];lp=p[lp].pre)
                p[lp].trs[c]=np;
            if(!lp)p[np].pre = 1;
            else
            {
                lq = p[lp].trs[c];
                if(p[lq].len == p[lp].len+1)p[np].pre = lq;
                else
                {
                    nq = ++tot;
                    p[nq] = p[lq];
                    p[nq].len = p[lp].len+1;
                    p[lq].pre = p[np].pre = nq;
                    while(p[lp].trs[c]==lq)
                    {
                        p[lp].trs[c]=nq;
                        lp=p[lp].pre;
                    }
                }
            }
            las = np;
            p[las].v.push_back(k);
        }
        int hed[2*N],cnt;
        struct EG
        {
            int to,nxt;
        }e[2*N];
        void ae(int f,int t)
        {
            e[++cnt].to = t;
            e[cnt].nxt = hed[f];
            hed[f] = cnt;
        }
        void dfs(int u)
        {
            tin[u]=++tim;pla[tim]=u;
            for(int j=hed[u];j;j=e[j].nxt)dfs(e[j].to);
            tout[u]=tim;
        }
        void build()
        {
            for(int i=2;i<=tot;i++)
                ae(p[i].pre,i);
            dfs(1);
        }
    }sam;
    int ans[60050],ct;
    struct Pair
    {
        int l,r,id;
    }qu[60050];
    bool cmp(Pair a,Pair b)
    {
        return a.r<b.r;
    }
    int f[2*N];
    void up(int x,int d)
    {
        if(!x)return ;
        while(x<=200000)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 las[10050];
    int main()
    {
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s+1);
            int len = strlen(s+1);
            sam.res();
            for(int j=1;j<=len;j++)
                sam.insert(ic(s[j]),i);
        }
        sam.build();
        for(int i=1;i<=q;i++)
        {
            scanf("%s",s+1);
            int len = strlen(s+1);
            int u = 1;
            for(int j=1;j<=len&&u;j++)
                u=sam.p[u].trs[ic(s[j])];
            if(u)
            {
                ct++;
                qu[ct].l = tin[u];
                qu[ct].r = tout[u];
                qu[ct].id = i;
            }
        }
        sort(qu+1,qu+1+ct,cmp);
        for(int k=1,i=1;i<=tim;i++)
        {
            for(int j=0;j<sam.p[pla[i]].v.size();j++)
            {
                up(i,1);
                up(las[sam.p[pla[i]].v[j]],-1);
                las[sam.p[pla[i]].v[j]]=i;
            }
            int tmp = down(i);
            for(;qu[k].r==i;k++)
                ans[qu[k].id] = tmp - down(qu[k].l-1);
        }
        for(int i=1;i<=q;i++)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Android 内存泄漏原因
    Android Selector和Shape的用法
    Android 中的Activity、Window、View之间的关系
    Android Application 详细介绍
    深入理解Android异步消息处理机制
    利用图像识别技术解决非原生控件的定位问题
    一招让 IOS 自动化化快的飞起
    IOS 模拟器多开集成测试和那些坑
    利用UiWatchers 监听解决安卓自动化各种自动化各种非期待弹窗,弹层,升级,广告,对话框,来电等问题
    uiautomatorviewer 优化定位符生成,支持生成Java,Python自动化代码
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10099155.html
Copyright © 2020-2023  润新知