bzoj1396

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1396

题目大意:

题解:后缀自动机,只出现一次,那么就是right值为1,那么对于一段1----L----R来说,(L----R)为一个最短识别子串对于(1----L-1)则可以用R-i+1来更新,对于(L---R)则可以用R-L+1来更新,那么两个线段树来维护即可。

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define maxn 100005
 7 using namespace std;
 8 char s[maxn];
 9 int n,m,tot,root;
10 bool v[maxn*2];
11 struct data{
12     int last,son[maxn*2][26],val[maxn*2],fa[maxn*2];
13     void prepare(){root=last=tot=1;}
14     int newnode(int x){val[++tot]=x; return tot;}
15     void extend(int x)
16     {
17         int p=last,np=newnode(val[p]+1); last=np;
18         for (; p && !son[p][x]; p=fa[p]) son[p][x]=np;
19         if (!p) fa[np]=root;
20         else
21         {
22             int q=son[p][x];
23             if (val[q]==val[p]+1) fa[np]=q;
24             else
25             {
26                 int nq=newnode(val[p]+1);
27                 memcpy(son[nq],son[q],sizeof(son[nq]));
28                 fa[nq]=fa[q];fa[q]=fa[np]=nq;
29                 for (; p && son[p][x]==q; p=fa[p]) son[p][x]=nq;
30              }
31          }
32     }
33     void build ()
34     {
35         for (int i=1; i<=n; i++) extend(s[i]-‘a‘);
36     }
37     void whoisfather()
38     {
39         for (int i=1; i<=tot; i++) v[fa[i]]=1;
40     }
41 }SAM;
42 struct T{
43     int mn[maxn*4];
44     T(){memset(mn,0x3f,sizeof(mn));}
45     void insert(int z,int l,int r,int x,int y,int w){
46         if(l>y||r<x) return;
47         if(l>=x&&r<=y){mn[z]=min(mn[z],w);return;}
48         int mid=(l+r)>>1;
49         insert(z*2,l,mid,x,y,w); insert(z*2+1,mid+1,r,x,y,w);
50     }
51     int query(int z,int l,int r,int x){
52         if(l==r&&l==x) return mn[z];
53         int mid=(l+r)>>1;
54         if(x<=mid) return min(mn[z],query(z*2,l,mid,x));
55         else return min(mn[z],query(z*2+1,mid+1,r,x));
56     }
57 }f,t;
58 int main()
59 {
60     scanf("%s",s+1); n=strlen(s+1);
61     SAM.prepare();
62     SAM.build();
63     SAM.whoisfather();
64     for (int i=1; i<=tot; i++)
65     {
66         if (!v[i])
67         {
68             int l=SAM.val[i]-SAM.val[SAM.fa[i]],r=SAM.val[i];
69             f.insert(1,1,n,l,r,r-l+1);
70             if (l>1) t.insert(1,1,n,1,l-1,r);
71         }
72     }
73     for (int i=1; i<=n; i++) printf("%d\n",min(f.query(1,1,n,i),t.query(1,1,n,i)-i+1));
74 }

注:oyzx神犇清早刷神题,我就只能默默写渣渣题。

  

时间: 2024-08-09 09:41:08

bzoj1396的相关文章

【bzoj1396】 识别子串

http://www.lydsy.com/JudgeOnline/problem.php?id=1396 (题目链接) 题意 问字符串S每一位的最短识别子串是多长(识别子串指包含这个字符且只出现在S中一次的子串). Solution 很简单,搞出后缀数组以后,对于每一个后缀i,都可以求出从i向后延伸的最短识别子串,也就是${max(height[rank[i]],height[rank[i]+1])+1}$,注意一种情况,就是i与排在它相邻位置的后缀的lcp就等于它自己的长度,这种情况i是没有向

【BZOJ1396】识别子串&amp;【BZOJ2865】字符串识别(后缀自动机)

[BZOJ1396]识别子串&[BZOJ2865]字符串识别(后缀自动机) 题面 自从有了DBZOJ 终于有地方交权限题了 题解 很明显,只出现了一次的串 在\(SAM\)的\(right/endpos\)集合大小一定为\(1\) 换句话说,在\(parent\)树上是叶子节点 找到所有这样的节点, 假设它的\(len=r\),它父亲的\(len=p\),它的结束位置为显然就是\(r\) 令\(l=r-p\) 以\(r\)结尾, 并且只出现了一次的串的左端点 为\(1..l\),那么,他们的答案

bzoj1396 识别子串

建SAM,只有right集大小为1的节点对答案有贡献, 若其出现位置右端点为r,此节点可接受的最短串长为x,最长串长为y, 则对(r-x,r]用x更新最小值,对r-k (y<k≤x)则用k更新最小值 用两棵线段树维护答案,分别处理以上两种情况 #include<cstdio> #include<cstring> const int N=200005; int nx[N][26],fa[N],l[N],r[N],t[N],q[N],ql=0,qr=0,d[N],ptr=1,pv

[BZOJ1396]识别子串 后缀自动机+线段树

1396: 识别子串 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 451  Solved: 290[Submit][Status][Discuss] Description Input 一行,一个由小写字母组成的字符串S,长度不超过10^5 Output L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. Sample Input agoodcookcooksgoodfood Sample Output 1 2 3 3

BZOJ1396&amp;2865 识别子串 【后缀自动机 + 线段树】

题目 输入格式 一行,一个由小写字母组成的字符串S,长度不超过10^5 输出格式 L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长. 输入样例 agoodcookcooksgoodfood 输出样例 1 2 3 3 2 2 3 3 2 2 3 3 2 1 2 3 3 2 1 2 3 4 题解 BZOJ AC200纪念,, 这两题题干是一样的,但唯一不同的是..后者卡空间[MLE得飞起] 先说解法: 我们知道后缀自动机上的parent树的每个节点子树中叶子的数量就是该节点

关于后缀自动机的总结

学习请看clj冬令营的讲稿吧,我是一点一点慢慢啃的…… 这里简单的说一下SAM的几个重要的性质 1.在SAM上,起点到任意一点的所有路径无重复的识别了所有子串 2.每个子串s出现的此处即ST(s)的right集合的大小(clj ppt中的定义) 具体的就是parent树上子树right集合的并(其实就是子树叶子节点个数) 3.(这是我认为最美妙的性质)SAM所构建出来的parent树与对原串逆序所购建出来的后缀树节点一一对应 具体的,SAM上每个节点最长接受子串=根节点到后缀树上每个点路径对应的

ZJOI2018未完成

1.BZOJ4521,BZOJ1396 2.洛谷DP,概率,数学 3.KD树,分治FFT 4.课件 https://ruanx.pw/post/有限微积分.html 原文地址:https://www.cnblogs.com/HocRiser/p/8605783.html