• P2336 [SCOI2012]喵星球上的点名(后缀自动机+莫队+dfs序)


    P2336 [SCOI2012]喵星球上的点名

    名字怎么存?显然是后缀自动机辣

    询问点到多少个喵喵喵其实就是

    查询后缀自动机上parent树的一个子树

    于是我们考虑莫队

    怎么树上莫队呢

    我们用dfs序处理后缀自动机上的parent树

    把parent树映射到序列上

    于是我们就可以愉快地莫队辣

    最后怎么处理每个喵喵喵被点到的次数呢

    我们在莫队的时候维护一个$Ls[i]$数组维护颜色$i$的存在时间(显然会被划分为好几段)

    当颜色$i$第一次进队(队内本来没有该颜色)时,就记下$Ls[i]$

    当队中最后一个颜色$i$出队时,答案就累加上$now-Ls[i]$,即为颜色$i$在这段的存在时间

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #define rint register int
    using namespace std;
    int read(){
        char c=getchar();int x=0;
        while(c<'0'||c>'9') c=getchar();
        while('0'<=c&&c<='9') x=x*10+(c^48),c=getchar();
        return x;
    }
    #define N 200005
    int n,m,Len,L,R,dfn[N],siz[N],Co[N];
    int tt,in[N],Ls[N],ans1[N],ans2[N],tot;
    int cnt,hd[N],nxt[N],ed[N],poi[N];
    struct data{int l,r,Id;}a[N];
    inline bool cmp(data A,data B){
        return (A.l/Len==B.l/Len)?A.r<B.r:A.l/Len<B.l/Len;
    }
    inline void adde(int x,int y){
        nxt[ed[x]]=++cnt, hd[x]=hd[x]?hd[x]:cnt,
        ed[x]=cnt, poi[cnt]=y;
    }
    struct Sam{
        int fa[N],len[N],col[N],ed,q,Clock;
        Sam(){Clock=0;ed=1;}
        map<int,int> mp[N];
        int add(int p,int x,int id){
            len[++ed]=len[p]+1; col[ed]=id;
            for(;p&&!mp[p][x];p=fa[p]) mp[p][x]=ed;
            if(!p) {fa[ed]=1;return ed;}
            q=mp[p][x];
            if(len[q]==len[p]+1){fa[ed]=q;return ed;}
            len[++ed]=len[p]+1; mp[ed]=mp[q];
            fa[ed]=fa[q]; fa[q]=fa[ed-1]=ed;
            for(;mp[p][x]==q;p=fa[p]) mp[p][x]=ed;
            return ed-1;
        }
        void link(){for(rint i=1;i<=ed;++i) adde(fa[i],i);}
        void dfs(int x){//dfs序把parent树映射到序列上
            dfn[x]=++Clock; Co[Clock]=col[x]; siz[x]=1;
            for(int i=hd[x];i;i=nxt[i])
                dfs(poi[i]),siz[x]+=siz[poi[i]];
        }
    }S;
    int main(){
        n=read();m=read();int q,now;
        for(rint i=1;i<=n;++i){
            q=read(); now=1;
            while(q--) now=S.add(now,read(),i);
            q=read(); now=1;
            while(q--) now=S.add(now,read(),i);
        }S.link(); S.dfs(1); Len=sqrt(S.ed);
        for(rint i=1;i<=m;++i){
            q=read();now=1;
            while(q--) now=S.mp[now][read()];
            if(!now) continue;
            a[++tt]=(data){dfn[now],dfn[now]+siz[now]-1,i};
        }
        if(tt){//在映射序列上进行莫队
            sort(a+1,a+tt+1,cmp);
            for(rint i=a[1].l;i<=a[1].r;++i){
                if(!in[Co[i]]&&Co[i]) ++tot,Ls[Co[i]]=1;
                ++in[Co[i]];
            }ans1[a[1].Id]=tot; L=a[1].l; R=a[1].r;
            for(rint i=2;i<=tt;++i){
                while(L<a[i].l){
                    --in[Co[L]];
                    if(!in[Co[L]]&&Co[L]) --tot,ans2[Co[L]]+=i-Ls[Co[L]];
                    ++L;
                }
                while(R>a[i].r){
                    --in[Co[R]];
                    if(!in[Co[R]]&&Co[R]) --tot,ans2[Co[R]]+=i-Ls[Co[R]];
                    --R;
                }
                while(L>a[i].l){
                    --L;
                    if(!in[Co[L]]&&Co[L]) ++tot,Ls[Co[L]]=i;
                    ++in[Co[L]];
                }
                while(R<a[i].r){
                    ++R;
                    if(!in[Co[R]]&&Co[R]) ++tot,Ls[Co[R]]=i;
                    ++in[Co[R]];
                }
                ans1[a[i].Id]=tot;
            }
            while(L<=R){
                --in[Co[L]];
                if(!in[Co[L]]&&Co[L]) --tot,ans2[Co[L]]+=tt-Ls[Co[L]]+1;
                ++L;
            }//注意最后剩下的数据要算进去
        }
        for(rint i=1;i<=m;++i) printf("%d
    ",ans1[i]);
        for(rint i=1;i<=n;++i) printf("%d ",ans2[i]);
        return 0;
    }
  • 相关阅读:
    架构师速成-怎样高效编程
    【论文笔记】Leveraging Datasets with Varying Annotations for Face Alignment via Deep Regression Network
    Redis数据类型--List
    python命令行传入参数
    python 连接ORacle11g
    sqlserver2016 kb补丁
    linux cat 文件编码
    python gtk 环境
    openstack kvm cannot set up guest memory 'pc.ram': Cannot allocate memory
    Mysql Explain 详解(转)
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/10713768.html
Copyright © 2020-2023  润新知