我是萌萌的傳送門
看來我的做法也沒錯嘛......
看別人的**,寫字尾陣列的好像是利用sa和height什麼的搞一搞,看了看表示沒看懂
看了看字尾自動機眾的**,好像是用什麼np->len-np->par->len更新答案,看了看表示理解不了
於是根據我對字尾自動機的理解強行yy了一發字尾自動機+dp的做法
我的想法是這樣的:
字尾自動機上每條從始態到終態的路徑與字尾一一對應,考慮到字尾自動機壓縮了冗餘狀態,相同的子串在字尾自動機上走出的路徑是會重合的
不難想到每條從始態到任意一點的路徑應該也和每乙個不同的子串一一對應,那麼我們只要求出從始態到任意一點的路徑數總和就好了
因為字尾自動機一定是dag(廢話,字尾和子串肯定是有限長的),只要跑一遍記憶化搜尋就行了
一開始跪的原因是以為開點順序一定是拓撲序,後來才想起來由於複製節點操作的存在開點順序不一定是拓撲序......
1 #include2 #include3 #include4view codeusing
namespace
std;
5const
int maxn=50010;6
void expand(int);7
void dfs(int);8
int root,last,cnt=0,val[maxn<<1]=,par[maxn<<1]=,go[maxn<<1][26]=};
9bool vis[maxn<<1]=;
10char
s[maxn];
11int n,f[maxn<<1]=;
12int
main()
23void expand(int
c)30
if(!p)par[np]=root;
31else45}
46}47 last=np;48}
49void dfs(int
x)56 }
SPOJ705 不同的子串
給定乙個字串,計算其不同的子串個數。一行乙個僅包含大寫字母的字串,長度 50000 一行乙個正整數,即不同的子串個數。ababa 題解 顯然字尾可以是乙個子串,然後字尾中可能包含多個子串。我們考慮不重複統計,容易發現 乙個字尾的貢獻為l high i 1 因為high i 之前的顯然可以在後面的串中...
spoj 705 求不同子串的個數(字尾陣列)
題意 給定乙個字串,求不相同的子串的個數。解題思路 對於乙個字尾sa k 它產生了n sa k 個字首,減去height k 個相同的字首 與前乙個比較 則產生了n sa k height k 個子串。累加後即結果。view code 1 2 author zhaofa fang 3 created...
spoj705 求不相同的子串個數
題意 求串s的不同子串的個數 解題思路 任何子串都是某個字尾的字首,對n個字尾排序,求某個字尾的字首的個數,減去height i 第i個字尾與第i 1 個字尾有相同的height i 個字首 如下 include include include include include include inc...