MFC單文件中進行plc點雲顯示
阿新 • • 發佈:2021-07-12
先對母串建立字尾自動機。
然後建出link樹。
然後,在link樹上算出每個節點的子樹大小,子樹大小*len[i]就是當前節點所表示的字串的長度乘出現次數。
坑:字尾自動機裡存在虛擬節點,這些節點的sz是0.
處理方法就是隻對cur記sz[cur]=1,對clone不管。
#include<bits/stdc++.h> using namespace std; const int maxn=4e6+10; int len[maxn],link[maxn],nxt[maxn][26]; int sz[maxn]; int tot=1,lst=1; string s; void sam_extend (char c) { int cur=++tot; len[cur]=len[lst]+1; sz[cur]=1; int p=lst; while (p&&!nxt[p][c-'a']) { nxt[p][c-'a']=cur; p=link[p]; } if (!p) { link[cur]=1; } else { int q=nxt[p][c-'a']; if (len[p]+1==len[q]) { link[cur]=q; } else { int clone=++tot; len[clone]=len[p]+1; for (int i=0;i<26;i++) { nxt[clone][i]=nxt[q][i]; } link[clone]=link[q]; while (p&&nxt[p][c-'a']==q) { nxt[p][c-'a']=clone; p=link[p]; } link[q]=link[cur]=clone; } } lst=cur; } vector<int> g[maxn]; void dfs (int u) { for (int v:g[u]) { dfs(v); sz[u]+=sz[v]; } } int main () { cin>>s; for (int i=0;i<s.size();i++) { sam_extend(s[i]); } for (int i=2;i<=tot;i++) g[link[i]].push_back(i); dfs(1); long long ans=0; for (int i=1;i<=tot;i++) { if (sz[i]>1) { ans=max(ans,1ll*len[i]*sz[i]); } } printf("%lld\n",ans); }