zoukankan      html  css  js  c++  java
  • AC日记——[SCOI2012]喵星球上的点名 bzoj 2754

    2754

    思路:

      AC自动机暴力处理匹配;

      强大的ac自动机,强大的fail树,强大的map,强大的vector,强大的指针;

    代码:

    #include <map>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 80005
    #define maxm 200005
    #define maxlen 400005
    
    struct TreeNodeType {
        int tag,id;
        
        TreeNodeType *fail;
        
        map<int,TreeNodeType*>next;
    
        TreeNodeType()
        {
            tag=0,id=0,fail=NULL,next.clear();
        }
    };
    struct TreeNodeType *que[maxlen],*root;
    
    int n,m,tot,ans2[maxn],ans1[maxn];
    
    map<int,bool>vis;
    
    vector<int>name[maxn],times[maxm];
    
    inline void in(int &now)
    {
        char Cget=getchar();now=0;
        while(Cget>'9'||Cget<'0') Cget=getchar();
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    
    int main()
    {
        freopen("name.in","r",stdin);
        freopen("name.out","w",stdout);
        root=new TreeNodeType,root->id=++tot;
        in(n),in(m);int len,pos;
        for(int i=1;i<=n;i++)
        {
            in(len);
            for(int j=1;j<=len;j++) in(pos),name[i].push_back(pos);
            name[i].push_back(-1),in(len);
            for(int j=1;j<=len;j++) in(pos),name[i].push_back(pos);
            name[i].push_back(-2);
        }
        for(int i=1;i<=m;i++)
        {
            in(len);TreeNodeType *now=root;
            for(int j=1;j<=len;j++)
            {
                in(pos);
                if(now->next[pos]==NULL)
                {
                    now->next[pos]=new TreeNodeType;
                    now->next[pos]->id=++tot;
                }
                now=now->next[pos];
            }
            now->tag++,times[now->id].push_back(i);
        }
        int h=0,tail=1;que[h]=root;
        while(h<tail)
        {
            TreeNodeType *now=que[h++],*temp=NULL;
            for(map<int,TreeNodeType*>::iterator it=now->next.begin();it!=now->next.end();it++)
            {
                if(now==root) it->second->fail=root;
                else
                {
                    temp=now->fail;
                    while(temp!=NULL)
                    {
                        if(temp->next[it->first])
                        {
                            it->second->fail=temp->next[it->first];
                            break;
                        }
                        temp=temp->fail;
                    }
                    if(temp==NULL) it->second->fail=root;
                }
                que[tail++]=it->second;
            }
        }
        for(int i=1;i<=n;i++)
        {
            len=name[i].size(),vis.clear();
            TreeNodeType *now=root,*temp;
            for(int j=0;j<len;j++)
            {
                if(!vis[now->id])
                {
                    vis[now->id]=true;
                    if(now->tag)
                    {
                        ans2[i]+=now->tag;
                        for(int v=0;v<times[now->id].size();v++) ans1[times[now->id][v]]++;
                    }
                    TreeNodeType *temp=now->fail;
                    while(temp!=NULL)
                    {
                        if(!vis[temp->id])
                        {
                            vis[temp->id]=true;
                            if(temp->tag)
                            {
                                ans2[i]+=temp->tag;
                                for(int v=0;v<times[temp->id].size();v++) ans1[times[temp->id][v]]++;
                            }
                        }
                        temp=temp->fail;
                    }
                }
                if(now->next[name[i][j]]) now=now->next[name[i][j]];
                else
                {
                    temp=now->fail;
                    while(temp!=NULL)
                    {
                        if(!vis[temp->id])
                        {
                            vis[temp->id]=true;
                            if(temp->tag)
                            {
                                ans2[i]+=temp->tag;
                                for(int v=0;v<times[temp->id].size();v++) ans1[times[temp->id][v]]++;
                            }
                        }
                        if(temp->next[name[i][j]])
                        {
                            now=temp->next[name[i][j]];
                            TreeNodeType *pos=temp->fail;
                            while(pos!=NULL)
                            {
                                if(!vis[pos->id])
                                {
                                    vis[pos->id]=true;
                                    if(pos->tag)
                                    {
                                        ans2[i]+=pos->tag;
                                        for(int v=0;v<times[pos->id].size();v++) ans1[times[pos->id][v]]++;
                                    }
                                }
                                pos=pos->fail;
                            }
                            break;
                        }
                        temp=temp->fail;
                    }
                    if(temp==NULL) now=root;
                }
            }
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans1[i]);
        for(int i=1;i<=n;i++)
        {
            if(i==1) printf("%d",ans2[i]);
            else printf(" %d",ans2[i]);
        }
        return 0;
    }
  • 相关阅读:
    box-shadow做出一条线两种颜色
    调取手机摄像头拍照并获取拍得的照片
    PHP请求第三方接口的函数
    PHP mysqli类
    PHP CI框架最近学到的内容
    GE_OG_CALC_COLUMN_EMPTY
    Oracle分区知识
    创建理想的SEQUENCE和自增长的trigger
    Oracle的大数据类型,BIG DATA TYPE
    FOREIGN KEY相关
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6858569.html
Copyright © 2011-2022 走看看