• 【贪心】【后缀自动机】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem E. Enter the Word


    题意:给你一个串,让你从左到右构造这个串,一次操作可以直接在当前串后面添加一个任意字符,或者拷贝当前串的任意一个子串到当前串的后面。问你最少要多少次操作才能构造出这个串。

    从前向后贪心,从当前已构造的串的后面开始,尽量往后走,尝试在后缀自动机上转移,直到不能转移为止,便求出了后面的串的在当前串中能找到的最长前缀是多少,然后答案++,然后把这个最长前缀加入后缀自动机接着跑即可。不会证明。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXL 200000
    #define MAXC 26
    int v[2*MAXL+10],__next[2*MAXL+10],first[2*MAXL+10],e;
    void AddEdge(int U,int V){
        v[++e]=V;
        __next[e]=first[U];
        first[U]=e;
    }
    char s[MAXL+10];
    int len;
    struct SAM{
        int endcnt[2*MAXL+10];
        int n,maxlen[2*MAXL+10],minlen[2*MAXL+10],trans[2*MAXL+10][MAXC],slink[2*MAXL+10];
        void clear(){
            for(int i=0;i<=n;++i){
                endcnt[i]=maxlen[i]=minlen[i]=slink[i]=first[i]=0;
                memset(trans[i],0,sizeof(trans[i]));
            }
            n=e=0;
        }
        int new_state(int _maxlen,int _minlen,int _trans[],int _slink){
            maxlen[n]=_maxlen;
            minlen[n]=_minlen;
            for(int i=0;i<MAXC;++i){
                if(_trans==NULL){
                    trans[n][i]=-1;
                }
                else{
                    trans[n][i]=_trans[i];
                }
            }
            slink[n]=_slink;
            return n++;
        }
        int add_char(char ch,int u){
            if(u==-1){
                return new_state(0,0,NULL,-1);
            }
            int c=ch-'a';
            int z=new_state(maxlen[u]+1,-1,NULL,-1);
            endcnt[z]=1;
            int v=u;
            while(v!=-1 && trans[v][c]==-1){
                trans[v][c]=z;
                v=slink[v];
            }
            if(v==-1){
                minlen[z]=1;
                slink[z]=0;
                return z;
            }
            int x=trans[v][c];
            if(maxlen[v]+1==maxlen[x]){
                minlen[z]=maxlen[x]+1;
                slink[z]=x;
                return z;
            }
            int y=new_state(maxlen[v]+1,-1,trans[x],slink[x]);
            slink[y]=slink[x];
            minlen[x]=maxlen[y]+1;
            slink[x]=y;
            minlen[z]=maxlen[y]+1;
            slink[z]=y;
            int w=v;
            while(w!=-1 && trans[w][c]==x){
                trans[w][c]=y;
                w=slink[w];
            }
            minlen[y]=maxlen[slink[y]]+1;
            return z;
        }
    }sam;
    int ans;
    int main(){
    //	freopen("e.in","r",stdin);
    	scanf("%s",s);
        len=strlen(s);
        int U=sam.add_char(0,-1);
        int i=0;
        while(i<len){
        	if(sam.trans[0][s[i]-'a']==-1){
        		U=sam.add_char(s[i],U);
        		++i;
        	}
        	else{
        		int j=i,V=0;
        		while(V!=-1 && j<len){
        			V=sam.trans[V][s[j]-'a'];
       	 			++j;
        		}
        		if(j==len && V!=-1){
        			++ans;
        			break;
        		}
        		for(int k=i;k<j-1;++k){
        			U=sam.add_char(s[k],U);
        		}
        		i=j-1;
        	}
        	++ans;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    在测试自定义starter时,若出现无法找到helloservice的Bean的解决方法
    springboot项目启动后tomcat服务器自动关闭 解决方法
    spring-ioc注解-理解2 零配置文件
    spring-ioc的注解 理解-1
    spring-ioc心得
    springboot的自动配置
    容器关系
    编写程序要做到结构、层次清晰明朗
    maven依赖的jar下载(在指定的仓库中)
    思考:开发的环境问题是一个大问题,也是首先要解决的问题,然后才能顺畅进入开发工作?
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7611590.html
Copyright © 2020-2023  润新知