題目鏈結
題意:給定乙個字串s,對於乙個整數k,定義s的子串t=s(i, j)是關於第k位的識別子串,滿足以下兩個條件:
1、i≤k≤j。
2、子串t只在s中出現過一次。
例如,s=「banana」,k=5,則關於第k位的識別子串有"nana",「anan」,「anana」,「nan」,「banan"和"banana」。
現在,給定s,求對於s的每一位,最短的識別子串長度是多少
題解:建出sam,我們發現可以作為識別子串需要只出現一次,所以就是sam的parent樹上的葉子節點。我們設l=l
en[i
]−le
n[fa
[i]]
l=len[i]-len[fa[i]]
l=len[
i]−l
en[f
a[i]
],r=le
n[i]
r=len[i]
r=len[
i],那麼對於i∈[
l,r]
i\in[l,r]
i∈[l,r
],ans[
i]=m
in=r
−l+1
ans[i]=min\=r-l+1
ans[i]
=min
=r−l
+1。因為父節點代表的串在子節點又出現過了,所以最短沒出現的就是父節點+1。
對於i ∈[
1,l)
i\in[1,l)
i∈[1,l
),因為[l,
r]
[l,r]
[l,r
]這一段是唯一的,所以加上乙個字首後仍是唯一的,於是可以用每個i
ii到r
rr的長度來更新答案,即r−i
+1
r-i+1
r−i+
1。而我們在回答時,i
ii是已知的,所以不用維護這個i
ii,我們只需要對每個位置維護最小的r
rr就行了。
於是我們需要開兩棵線段樹,分別維護兩種情況的答案,然後取個min即可。
**:
#include
using
namespace std;
int n,fa[
400010
],ch[
400010][
26],len[
400010
],sz[
400010
],lst=
1,rt=
1,cnt=1;
int vis[
400010];
char s[
100010];
struct node
tr1[
1600010
],tr2[
1600010];
inline
void
insert
(int x)}}
inline
void
build
(int rt,
int l,
int r)
int mid=
(l+r)
>>1;
build
(rt<<
1,l,mid)
;build
(rt<<1|
1,mid+
1,r)
; tr1[rt]
.mn=
2e9;
tr2[rt]
.mn=
2e9;
}inline
void
pushdown1
(int rt)
inline
void
update1
(int rt,
int le,
int ri,
int x)
pushdown1
(rt)
;int mid=
(l+r)
>>1;
if(le<=mid)
update1
(rt<<
1,le,ri,x);if
(mid+
1<=ri)
update1
(rt<<1|
1,le,ri,x)
; tr1[rt]
.mn=
min(tr1[rt<<1]
.mn,tr1[rt<<1|
1].mn);}
inline
void
pushdown2
(int rt)
inline
void
update2
(int rt,
int le,
int ri,
int x)
pushdown2
(rt)
;int mid=
(l+r)
>>1;
if(le<=mid)
update2
(rt<<
1,le,ri,x);if
(mid+
1<=ri)
update2
(rt<<1|
1,le,ri,x)
; tr2[rt]
.mn=
min(tr2[rt<<1]
.mn,tr2[rt<<1|
1].mn);}
inline
intquery1
(int rt,
int x)
inline
intquery2
(int rt,
int x)
intmain()
}for
(int i=
1;i<=n;
++i)
printf
("%d\n"
,min
(query1(1
,i),
query2(1
,i)-i+1)
);return0;
}
bzoj1396識別子串(SAM 線段樹)
複習sam板子啦!考前刷水有益身心健康當然這不是板子題 水題 很容易發現只在i位置出現的串一定是個字首串。那麼對答案的貢獻分成兩部分 一部分是len x fa len x 的這部分貢獻會是r l 1 剩下一部分1 len fa 1這部分會和i r構成答案,寫兩棵線段樹即可。然後就又是板子題了,兩個板...
BZOJ 1396 識別子串
solution 我得了 能用字尾陣列就一定不用字尾自動機綜合症 感覺用height rank sa 處理字串真的好優雅 雖然其他題上字尾陣列常數比較大 不過這個字尾陣列水了一發似乎就rank1 了 開心 題解就是求出字尾陣列以後維護乙個單調佇列來更新答案啦。include include incl...
Bzoj1396 識別子串
i 1,n i 1,n 求包含 i i 並且在原串 s role presentation style position relative s s中只出現一次的子串的最短長度 因為每個點pa rent p ar en t樹上的父親肯定是當前節點所代表的串的字尾 那麼只出現一次的串就是pa rent ...