• 【工艺】


    好像是最小表示法的板子题呢

    但是不会啊,于是就变成了我的第一道(SAM)

    对于这种跟循环同构有关系的题,显然需要将原来的串倍长,之后先插入到(SAM)里去

    之后我们在(SAM)上找到贪心访问最小的儿子找到一条长度为(n)的路径就好了

    显然因为我们循环同构了,所以从根到根的任何一个转移必然会存在一个长度为(n)的路径

    字符集很大,需要开(map)

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #define re register
    #define LL long long
    #define maxn 600005
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
    	re char c=getchar();int x=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    std::map<int,int> son[maxn<<1];
    int a[maxn];
    int link[maxn<<1],len[maxn<<1],sz[maxn<<1];
    int lst=1,n,m,cnt=1,now=0;
    inline void ins(int c)
    {
    	int f=lst,p=++cnt; lst=p;
    	len[p]=len[f]+1,sz[p]=1;
    	while(f&&!son[f][c]) son[f][c]=p,f=link[f];
    	if(!f) {link[p]=1;return;}
    	int x=son[f][c];
    	if(len[f]+1==len[x]) {link[p]=x;return;}
    	int y=++cnt;
    	len[y]=len[f]+1,link[y]=link[x],link[x]=link[p]=y;
    	for(std::map<int,int>::iterator i=son[x].begin();i!=son[x].end();++i) son[y].insert(*i);
    	while(f&&son[f][c]==x) son[f][c]=y,f=link[f];
    }
    void dfs(int x)
    {
    	if(now==n) return;
    	std::map<int,int>::iterator i=son[x].begin();
    	int t=(*i).first;
    	printf("%d ",t);now++;
    	dfs((*i).second);
    }
    int main()
    {
    	n=read();
    	for(re int i=1;i<=n;i++) a[i]=a[i+n]=read();
    	for(re int i=1;i<=2*n;i++) ins(a[i]);
    	dfs(1);
    	return 0;
    }
    
  • 相关阅读:
    一、入门实例
    十四、事物配置
    JAVA-调用http链接
    ORACLE 年龄计算到月份
    ORACLE和MYSQL 去重查询
    JAVA--将图片转为BASE64编码并返回thymeleaf页面
    JAVA--将图片保存至项目路径
    java--获取类加载路径和项目根路径
    excel执行INSERT和UPDATE操作语句
    c# 未能加载Oracle.DataAccess, Version=2.112.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342
  • 原文地址:https://www.cnblogs.com/asuldb/p/10207916.html
Copyright © 2020-2023  润新知