zoukankan      html  css  js  c++  java
  • jzoi4964

    思路是先对每个(k-1)长度的子字符串之间建边,然后拓扑,若有环则最终仍有indg[i]为 0的

    这题用字符串哈希的话会超时

    以下是30分做法

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define mo 9223372036854775807
    #define ll unsigned long long
    using namespace std;
    const int maxn=1e5+2;
    const int hx=2000000;
    int n,k,cnt,to[maxn],ans,head[maxn],nex[maxn],indg[hx],dis[hx];
    char s[maxn];
    bool vis[hx];
    queue<int>q;
    ll hsh[hx];
    ll ksm(int x,int y){
        ll t=1;
        while(y){
            if(y&1)t=t*x%mo;
            x=x*x%mo;
            y>>=1;
        }
        return t;
    }
    ll hash(ll x){
        ll pos=x%hx;
        while(hsh[pos]&&hsh[pos]!=x)pos=(pos+1)%hx;
        hsh[pos]=x;
        return pos;
    }
    void addedge(int u,int v){
        indg[v]++;vis[u]=vis[v]=1;
        to[++cnt]=v;nex[cnt]=head[u];head[u]=cnt;
    }
    void topo(){
        while(!q.empty()){
            int u=q.front();q.pop();
            ans=max(ans,dis[u]);
            for(int i=head[u];i;i=nex[i]){
                int v=to[i];
                dis[v]=max(dis[v],dis[u]+1);
                if(!(--indg[v]))q.push(v);
            }
        }
    }
    int main(){
        while(~scanf("%d%d",&n,&k)){
            ll kk=ksm(26,k-1);
            cnt=1;
            memset(head,0,sizeof(head));
            memset(indg,0,sizeof(indg));
            memset(vis,0,sizeof(vis));
            while(n--){
                scanf("%s",s+1);
                int len=strlen(s+1);
                if(len<k)continue;
                for(int i=1;i<=len;i++)s[i]=s[i]-'a'+1;
                ll t=0;
                for(int i=1;i<k;i++)t=t*26+s[i];
                for(int i=k;i<=len;i++){
                    ll u=hash(t);
                    t=t*26+s[i]-kk*s[i-k+1];
                    ll v=hash(t);
                    addedge(u,v);
                }
            }
            ans=k-1;
            for(int i=0;i<hx;i++)
               if(vis[i]&&!indg[i]){q.push(i);dis[i]=k-1;}
            topo();
            bool flag=0;
            for(int i=0;i<hx;i++)if(indg[i]){
                flag=1;break;
            }
            if(flag)printf("INF\n");else printf("%d\n",ans);
        }
    }

    满分用map

    #include<cstdio>
    #include<string>
    #include<map>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int maxn=1e5,hx=6e6;
    string s[maxn];
    int n,k,ans,cnt,tot,nex[hx],head[hx],to[hx],dis[hx],vis[hx],indg[hx];
    map<string,int>m;
    int hash(string ss){
        int &pos=m[ss];
        if(!pos)pos=++tot;
        return pos;
    }
    void addedge(int u,int v){
        indg[v]++;to[++cnt]=v;nex[cnt]=head[u];head[u]=cnt;
    }
    queue<int>q;
    void topo(){
        while(!q.empty()){
            int u=q.front();q.pop();
            ans=max(ans,dis[u]);
            for(int i=head[u];i;i=nex[i]){
                dis[to[i]]=max(dis[to[i]],dis[u]+1);
                if(--indg[to[i]]==0)
                q.push(to[i]);
            }
        }
    }
    int main(){
        while(~scanf("%d%d",&n,&k)){
            cnt=tot=ans=0;
            memset(head,0,sizeof(head));
            memset(vis,0,sizeof(vis));
            memset(dis,0,sizeof(dis));
            memset(indg,0,sizeof(indg));
            m.clear();
            for(int i=1;i<=n;i++){
                cin>>s[i];
                for(int j=0;j+k-1<s[i].size();j++){
                    addedge(hash(s[i].substr(j,k-1)),hash(s[i].substr(j+1,k-1)));
                }
            }
            for(int i=1;i<=tot;i++)
            if(!indg[i])
            q.push(i);
            topo();
            bool flag=0;
            for(int i=1;i<=tot;i++)if(indg[i]>0){flag=1;break;}
            if(flag)printf("INF\n");else printf("%d\n",ans+k-1);
        }
    }
  • 相关阅读:
    Java设计模式—单例模式
    Java集合框架
    Java进程和线程
    Java IO
    Java异常类
    Java面向对象—抽象类和接口
    Java面向对象—多态
    Java面向对象—继承
    Java面向对象
    Java基础语法
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/8977429.html
Copyright © 2011-2022 走看看