zoukankan      html  css  js  c++  java
  • SP8093 JZPGYZ

    SP8093 JZPGYZ - Sevenk Love Oimaster

    题目大意

    给定(n(nle 10000))个模板串,以及(m(mle 60000))个查询串(模板串总长(le 100000),询问串总长(le 360000)

    依次查询每一个查询串是多少个模板串的子串


    先对模板串建广义SAM(每次新串las=1的那种)

    然后考虑每个点都有一个所属的模板串,它可以对par树上到跟的那条链产生贡献,可以暴力加,据说均摊(O(nsqrt n)),不清楚...

    反正是链的问题,不如直接转换成子树问题。

    然后发现询问就变成了查询某个点子树和,放到dfs序上发现是区间数颜色,可以离线

    于是像HH的项链那样直接树状数组维护一下就可以了。


    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    const int N=2e5+10;
    int len[N],par[N],ch[N][26],col[N],id,tot=1,las=1;
    void extend(int c)
    {
        int now=++tot,p=las;
        len[now]=len[p]+1,col[now]=id;
        while(p&&!ch[p][c]) ch[p][c]=now,p=par[p];
        if(!p) par[now]=1;
        else
        {
            int x=ch[p][c];
            if(len[x]==len[p]+1) par[now]=x;
            else
            {
                int y=++tot;
                len[y]=len[p]+1,par[y]=par[x],col[y]=id;
                memcpy(ch[y],ch[x],sizeof ch[x]);
                while(p&&ch[p][c]==x) ch[p][c]=y,p=par[p];
                par[now]=par[x]=y;
            }
        }
        las=now;
    }
    int head[N],to[N],Next[N],cnt;
    void add(int u,int v)
    {
        to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
    }
    int dfn[N],low[N],ha[N],dfsclock;
    void dfs(int now)
    {
        ha[dfn[now]=++dfsclock]=now;
        for(int i=head[now];i;i=Next[i]) dfs(to[i]);
        low[now]=dfsclock;
    }
    struct node
    {
        int id,l,r;
        node(){}
        node(int id,int l,int r){this->id=id,this->l=l,this->r=r;}
        bool friend operator <(node n1,node n2){return n1.r<n2.r;}
    }q[N];
    int n,m,m_,pre[N],su[N],ans[N];
    char s[N];
    void modify(int x,int d){while(x<=dfsclock)su[x]+=d,x+=x&-x;}
    int query(int x){int s=0;while(x)s+=su[x],x-=x&-x;return s;}
    int main()
    {
        scanf("%d%d",&n,&m);
        for(id=1;id<=n;id++)
        {
            scanf("%s",s+1);
            las=1;int k=strlen(s+1);
            for(int j=1;j<=k;j++) extend(s[j]-'a');
        }
        for(int i=2;i<=tot;i++) add(par[i],i);
        dfs(1);
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s+1);
            int now=1,k=strlen(s+1);
            for(int j=1;j<=k;j++)
            {
                now=ch[now][s[j]-'a'];
                if(!now) break;
            }
            if(now) q[++m_]=node(i,dfn[now],low[now]);
        }
        std::sort(q+1,q+1+m_);
        for(int j=1,i=1;i<=dfsclock;i++)
        {
            int color=col[ha[i]];
            if(pre[color]) modify(pre[color],-1);
            modify(pre[color]=i,1);
            while(j<=m_&&q[j].r<=i) ans[q[j].id]=query(q[j].r)-query(q[j].l-1),++j;
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    

    2019.1.10

  • 相关阅读:
    白盒测试实践——每日例会记录(九)
    白盒测试实践——每日例会记录(八)
    白盒测试实践——每日例会记录(七)
    白盒测试实践——每日例会记录(六)
    白盒测试实践——每日例会记录(五)
    白盒测试实践——每日例会记录(四)
    白盒测试实践——每日例会记录(三)
    codeforces 常用模板总结
    Codeforces 118A String Task
    Codeforces 158A Next Round
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10249967.html
Copyright © 2011-2022 走看看