• 洛谷 P3975 [TJOI2015]弦论【SAM】


    传送门
    后缀自动机的经典题了。
    统计每个节点的 (endpos),如果不同位置相同串算 1 个的话,所有点的 (endpos) 都为 1 就行了。因为空串不算,所以 1 点的 (endpos=0)
    然后在 DAG 上 DP 把每个点能遍历到的点的总值算出来,这个值就代表了以这个点开头的子串个数。
    最后在 DAG 走一下就可以了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=5e5+10;
    int n,k,flag;
    char s[N];
    struct SuffixAutoMachine{
    	int last=1,tot=1,ch[N*2][26],fa[N*2],len[N*2],c[N],a[N*2],epos[N*2];
    	LL sum[N*2];
    	int newnode(int x){fa[++tot]=fa[x];len[tot]=len[x];memcpy(ch[tot],ch[x],sizeof(ch[tot]));return tot;}
    	void append(int c){
    		int p=last,np=last=newnode(0);
    		len[np]=len[p]+1;epos[np]=1;
    		for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    		if(!p) {fa[np]=1;return;}
    		int q=ch[p][c];
    		if(len[q]==len[p]+1) {fa[np]=q;return;}
    		int nq=newnode(q);len[nq]=len[p]+1;epos[nq]=0;
    		fa[q]=fa[np]=nq;
    		for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    	}
    	void init(){
    		for(int i=1;i<=n;i++) append(s[i]-'a');
    		for(int i=1;i<=tot;i++) c[len[i]]++;
    		for(int i=1;i<=n;i++) c[i]+=c[i-1];
    		for(int i=tot;i>=1;i--) a[c[len[i]]--]=i;
    		for(int i=tot;i>1;i--) epos[fa[a[i]]]+=epos[a[i]];
    		if(!flag) for(int i=1;i<=tot;i++) epos[i]=1;
    		epos[1]=0;
    		for(int i=tot;i>=1;i--){
    			int u=a[i];sum[u]=epos[u];
    			for(int j=0;j<26;j++)
    				if(ch[u][j]) sum[u]+=sum[ch[u][j]];
    		}
    		if(sum[1]<k) {printf("-1
    ");return;}
    		int p=1;
    		while(k>epos[p]){
    			k-=epos[p];
    			for(int i=0;i<26;i++){
    				if(!ch[p][i]) continue;
    				if(k>sum[ch[p][i]]) {k-=sum[ch[p][i]];continue;}
    				printf("%c",'a'+i);
    				p=ch[p][i];break;
    			}
    		}
    	}
    }sam;
    
    int main(){
    	scanf("%s%d%d",s+1,&flag,&k);
    	n=strlen(s+1);
    	sam.init();
    	return 0;
    }
    
  • 相关阅读:
    黑马程序员_使用Jquery实现AJAX功能
    BootStrap 推荐网站
    工具类
    ExtJS 模块案例(增删改查)
    sql server 经典语句。~转 (入门必看)
    sql 时间格式转换
    转载wuhuacong(伍华聪)的专栏 利用Aspose.Word控件实现Word文档的操作 (留作笔记)
    c#操作Word文件 导出数据到word文档 (table 书签方式)
    ExtJs之格式化(Ext.util.Format) ~转
    查询/修改XML里某个字段的值
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12670843.html
Copyright © 2020-2023  润新知