2017 ACM/ICPC Asia Regional Qingdao Online 1003 The Dominator of Strings

题目链接:

http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1003&cid=778

题解:

STM,队友讲题意的时候漏掉了范围。。。。。。
强行AC自动机。

代码:

#include<cstdio>
#include<cstring>
#define M 100000+10
using namespace std;
struct AC{
    int root,en,my_que[M];
    struct E{
        int flag,fail;
        int next[26];
    }e[M];
    void flash(int id){
        e[id].flag=0;
        memset(e[id].next,-1,sizeof(e[id].next));
    }
    void init(){
        root=0;en=1;
        flash(root);
        e[root].fail=-1;
    }
    void insert(char *p){
        int tr=root;
        for(int i=0;p[i];i++){
            int dex=p[i]-'a';
            if(e[tr].next[dex]==-1){
                int t2=en++;flash(t2);
                e[tr].next[dex]=t2;
            }
            tr=e[tr].next[dex];
        }
        e[tr].flag++;
    }
    void build(){
        int hp=0,tp=-1;
        my_que[++tp]=root;
        while(tp>=hp){
            int now=my_que[hp++];
            for(int i=0;i<26;i++){
                if(e[now].next[i]!=-1){
                    int nxt=e[now].next[i];
                    int dex=i;
                    if(now==root){
                        e[nxt].fail=root;
                    }
                    else{
                        int tmp=e[now].fail;
                        while(tmp!=-1&&e[tmp].next[dex]==-1) tmp=e[tmp].fail;
                        if(tmp==-1) tmp=root;
                        else tmp=e[tmp].next[dex];
                        e[nxt].fail=tmp;
                    }
                    my_que[++tp]=nxt;
                }
            }
        }
    }
    int query(char *p){
        int ans=0;
        int tr=root;
        for(int i=0;p[i];i++){
            int dex=p[i]-'a';
            while(e[tr].next[dex]==-1&&tr!=root)tr=e[tr].fail;
            tr=e[tr].next[dex];
            if(tr==-1)tr=root;
            int tmp=tr;
            while(tmp!=root&&e[tmp].flag!=-1){
                ans+=e[tmp].flag;
                e[tmp].flag=-1;
                tmp=e[tmp].fail;
            }
        }
        return ans;
    }
}ac;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ac.init();
        char pre[M],now[M];
        int n;
        scanf("%d",&n);
        scanf("%s",pre);
        int MAX=strlen(pre);
        for(int i=1;i<n;i++)
        {
            scanf("%s",now);
            int len=strlen(now);
            if(len>MAX)
            {
                ac.insert(pre);
                MAX=len;
                strcpy(pre,now);
            }
            else
                ac.insert(now);
        }
        ac.build();
        int cnt=ac.query(pre);
        if(cnt!=n-1)
            printf("No\n");
        else
            printf("%s\n",pre);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值