Bzoj1396 識別子串

2021-08-17 10:26:24 字數 2487 閱讀 3531

∀i

∈[1,

n]∀ i∈

[1,n

]求包含

i i

並且在原串

s' role="presentation" style="position: relative;">s

s中只出現一次的子串的最短長度

因為每個點pa

rent

p ar

en

t樹上的父親肯定是當前節點所代表的串的字尾

那麼只出現一次的串就是pa

rent

p ar

en

t樹上的葉子節點

考慮這個點所代表的le

n[i]

−len

[fa[

i]] len

[i]−

len[

fa[i

]]

個子串令l

=len

[i]−

len[

fa[i

]],r

=len

[i] l=l

en[i

]−le

n[fa

[i]]

,r=l

en[i

]1.∀

i∈[l

,r],

ans[

i]=m

in=m

in1.∀i

∈[l,

r],a

ns[i

]=mi

n=mi

n因為父親節點所代表的串都在葉子裡出現過了,所以最短沒出現的子串長度就是父親的長度加

1 1

2.∀i

∈[1,

l),s

[i,r

]' role="presentation" style="position: relative;">2.∀i

∈[1,

l),s

[i,r

]2.∀i

∈[1,

l),s

[i,r

]這個子串出現次數也是

1 1

那麼an

s[i]

=min

=min

−i' role="presentation" style="position: relative;">ans

[i]=

min=

min−

ians

[i]=

min=

min−

i 上面的東西涉及到區間修改和區間求最小值,用兩顆線段樹維護一下就好了

#include

#define fp(i,a,b) for(register int i=a,i=b+1;i#define fd(i,a,b) for(register int i=a,i=b-1;i>i;--i)

#define go(u) for(register int i=fi[u],v=e[i].to;i;v=e[i=e[i].nx].to)

#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)

template

inline

bool cmax(t&a,const t&b)

template

inline

bool cmin(t&a,const t&b)

using

namespace

std;

char sr[1

<<21],z[20];int c=-1,z;

inline

void ot()

template

inline

void we(t x)

const

int n=1e5+5,m=2*n,inf=1061109567;

typedef

long

long ll;

typedef

int arr[m];

int n,k;char s[n];string str[n];

struct seg

inline

void cov(int p,int w)

inline

void down(int p)

void mdy(int p,int l,int r,int a,int b,int w)

int qry(int p,int l,int r,int a)

#undef lc

#undef rc

}t1,t2;

struct sam

inline

void ins(int c)

}}arr fg;

inline

void sol(int n)

fp(i,1,n)we(min(t1.qry(1,1,n,i)-i,t2.qry(1,1,n,i)));

}}p;int main()

BZOJ 1396 識別子串

solution 我得了 能用字尾陣列就一定不用字尾自動機綜合症 感覺用height rank sa 處理字串真的好優雅 雖然其他題上字尾陣列常數比較大 不過這個字尾陣列水了一發似乎就rank1 了 開心 題解就是求出字尾陣列以後維護乙個單調佇列來更新答案啦。include include incl...

BZOJ1396 識別子串

列舉左端點 i 那麼可行的右端點 j 的最小值單調不下降,可以通過雙指標求出,檢驗可以通過在字尾陣列裡檢查相鄰height值做到 o 1 那麼左端點為 i 右端點在 j,n 它對前面一段的貢獻為定值,對後面一段的貢獻為等差數列,線段樹維護即可。時間複雜度 o n log n include incl...

bzoj1396 識別子串

solution 只出現一次的點只能是葉子。假設某乙個葉子表示的區間是 1 max 它的父親的長度是m。也就是 max m,max 只出現過一次。那麼我們可以用這m 1長來更新 max m,max a 剩下 1,max m 的位置x,可以用 x,max 這段區間的長度來更新。b 於是按下標開兩棵線段...