zoukankan      html  css  js  c++  java
  • CF271D Good Substrings SAM

    题意:

    戳这里

    分析:

    建出SAM,然后 (dfs) 将不好字符的转移代价设置为 (1) ,好的字符的转移代价设置为 (0) 这样题意等价于求本质不同的长度小于等于 (k) 的字符串个数,(O(nk)) 的转移就行了

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	inline int read()
    	{
    		int x=0,f=1;char ch=getchar();
    		while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    		while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    		return x*f;
    	}
        
        const int maxn = 1e4+5;
        int n,k;
        int f[maxn][1505];
        char ch[maxn];
        bool vis[maxn],chk[26];
    
        struct suffix_automaton
        {
            int cnt,lst;
            int link[maxn],trans[maxn][26],len[maxn];
            suffix_automaton(){cnt=lst=1;}
    
            void insert(int x)
            {
                int cur=++cnt,tmp=lst;lst=cnt;
                len[cur]=len[tmp]+1;
                for(;tmp&&!trans[tmp][x];tmp=link[tmp]) trans[tmp][x]=cur;
                if(!tmp)
                {
                    link[cur]=1;
                }
                else
                {
                    int q=trans[tmp][x];
                    if(len[tmp]+1==len[q])
                    {
                        link[cur]=q;
                    }
                    else
                    {
                        int clone=++cnt;
                        len[clone]=len[tmp]+1;
                        link[clone]=link[q];
                        link[cur]=link[q]=clone;
                        for(int i=0;i<26;i++) trans[clone][i]=trans[q][i];
                        for(;tmp&&trans[tmp][x]==q;tmp=link[tmp]) trans[tmp][x]=clone;
                    }
                }
            }
    		
    		void dfs(int u=1)
    	    {
    	        vis[u]=true;
    	        for(int i=0;i<26;i++)
    	        {
    	            int v=trans[u][i];
    	            if(!v) continue;
    	            if(!vis[v]) dfs(v);
    	            f[u][chk[i]]++;
    	            for(int j=0;j<=k;j++) if(j-chk[i]>=0) f[u][j]+=f[v][j-chk[i]];
    	        }
    	    }
    	
        }sam;
    
    	void work()
    	{
    	    scanf("%s",ch+1);n=strlen(ch+1);
            for(int i=1;i<=n;i++) sam.insert(ch[i]-'a');
            scanf("%s",ch);
            for(int i=0;i<26;i++) chk[i]=(ch[i]=='0');
            k=read();
            sam.dfs();
            long long ans=0;
            for(int i=0;i<=k;i++) ans+=f[1][i];
            printf("%lld
    ",ans);
    	}
    
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
    
  • 相关阅读:
    java Socket Tcp 浏览器和服务器(二)
    java Socket Tcp 浏览器和服务器(一)
    java Socket Tcp示例三则(服务端处理数据、上传文件)
    java Socket Udp聊天
    centos 图形界面和命令行界面切换
    python 文件中的中文编码解决方法
    PostgreSQL与MySQL比较(转)
    Python 的开发环境
    Windows 下 pip和easy_install 的安装与使用
    Linux 下的下载文件命令
  • 原文地址:https://www.cnblogs.com/youth518/p/14221763.html
Copyright © 2011-2022 走看看