zoukankan      html  css  js  c++  java
  • 【工艺】

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

    但是不会啊,于是就变成了我的第一道(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;
    }
    
  • 相关阅读:
    Linux下find命令详解
    shell if语句
    目标文件系统映像制作工具mkyaffs2image
    编译内核
    FPS含义
    linux下echo命令详解
    Mssql数据库语句综合
    string 字符串操作
    Lession 15 Good news
    Mysql使作心得(备份,还原,乱码处理)
  • 原文地址:https://www.cnblogs.com/asuldb/p/10207916.html
Copyright © 2011-2022 走看看