題解:
首先我們知道對於size==1的點是只出現一次的
存疑:為什麼新增點不會size==1
那麼問題就變成區間取等差數列,區間取最小值
分別線段樹維護就可以了
**:
#include #define il inline#define ll long long
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
using
namespace
std;
const
int inf=1e9;
const
int n=3e5;
char
s[n];
int size[n],len[n],ch[n][26
];int lst=1,node=1
,t[n],a[n],fa[n],pos[n],pl;
void extend(int
c)
int p=++node; lst=p;
len[p]=len[f]+1; //
size[p][pl]=1;
while (f&&!ch[f][c]) ch[f][c]=p,f=fa[f];
if (!f) ;
int x=ch[f][c],y=++node;
if (len[f]+1==len[x]) ;
len[y]=len[f]+1; fa[y]=fa[x]; fa[x]=fa[p]=y;
memcpy(ch[y],ch[x],
sizeof
(ch[x]));
while (f&&ch[f][c]==x) ch[f][c]=y,f=fa[f];
}il
int min(int x,int
y)il
int max(int x,int
y)il
void minn(int &x,int
y)il
void maxn(int &x,int
y)const
int n1=n*4
;struct
sgt
#define mid ((h+t)/2)il
void down(int x,int h,int
t)
void change1(int x,int h,int t,int h1,int t1,int
k)
down(x,h,t);
if (h1<=mid) change1(x*2
,h,mid,h1,t1,k);
if (mid2+1,mid+1,t,h1,t1,k-(mid-h+1
)); }
void change2(int x,int h,int t,int h1,int t1,int
k)
down(x,h,t);
if (h1<=mid) change2(x*2
,h,mid,h1,t1,k);
if (mid2+1,mid+1
,t,h1,t1,k);
} int query(int x,int h,int t,int
pos)
down(x,h,t);
if (pos<=mid) return(query(x*2
,h,mid,pos));
else
return(query(x*2+1,mid+1
,t,pos));
}}s;
intmain()
rep(i,
1,node)
if (size[i]==1)
rep(i,
1,n)
cout
<1,1,n,i)
}
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 ...
BZOJ1396 識別子串
列舉左端點 i 那麼可行的右端點 j 的最小值單調不下降,可以通過雙指標求出,檢驗可以通過在字尾陣列裡檢查相鄰height值做到 o 1 那麼左端點為 i 右端點在 j,n 它對前面一段的貢獻為定值,對後面一段的貢獻為等差數列,線段樹維護即可。時間複雜度 o n log n include incl...