SPOJ NSUBSTR
題意:
給出一個字串,求這個字串長度為1-n的子串的最大出現次數;
字串長度<=250000;
題解:
幾天沒更新,水一發字尾自動機的題解吧;
首先定義字尾自動機的的right集合大小,就是該結點代表的狀態能拓展到的子串種類;
那麼對於長度為x的子串的答案就是所有長度>=x的結點的right值的最大值;
right值是不能再構建自動機時增量維護的,所以只能在構建這個字尾自動機之後再O(n)搞一遍;
具體就是從反向字尾樹的葉子開始,定義每個關鍵節點的right初始都為1,然後順著求出所有節點的子樹和就可以了;
然後再用right[x]更新f[len[x]],掃一遍讓f[i]=max(f[i],f[i+1]);
時間複雜度O(n);
然而後綴自動機的構建依然是基本靠背的程式碼。。
而且大概字尾自動機順便建出來的反向字尾樹比那個識別字尾的本體要有用得多。。真是233
程式碼:
#include<queue> #include<stdio.h> #include<string.h> #include<algorithm> #define N 260000 #define S 26 using namespace std; char str[N]; int f[N]; namespace SAM { int son[N<<1][S],len[N<<1],pre[N<<1]; int in[N<<1],right[N<<1]; int tot,last; queue<int>q; int newnode() { tot++; memset(son[tot],0,sizeof(int)*S); pre[tot]=len[tot]=0; return tot; } void init() { tot=0; last=newnode(); } void Insert(int x) { int p,np=newnode(); right[np]=1; len[np]=len[last]+1; for(p=last;p&&!son[p][x];p=pre[p]) son[p][x]=np; if(!p) pre[np]=1; else { int q=son[p][x]; if(len[q]==len[p]+1) pre[np]=q; else { int nq=newnode(); pre[nq]=pre[q]; len[nq]=len[p]+1; memcpy(son[nq],son[q],sizeof(int)*S); pre[np]=pre[q]=nq; for(;son[p][x]==q;p=pre[p]) son[p][x]=nq; } } last=np; } void Build() { int x,i; for(i=1;i<=tot;i++) { in[pre[i]]++; } for(i=1;i<=tot;i++) { if(!in[i]) q.push(i); } while(!q.empty()) { x=q.front(),q.pop(); in[pre[x]]--; right[pre[x]]+=right[x]; if(!in[pre[x]]) q.push(pre[x]); } } void calc(int n) { for(int i=1;i<=tot;i++) f[len[i]]=max(f[len[i]],right[i]); for(int i=n-1;i>=1;i--) f[i]=max(f[i],f[i+1]); } } int main() { int n,m,i,j,k; scanf("%s",str+1); n=strlen(str+1); SAM::init(); for(i=1;i<=n;i++) { SAM::Insert(str[i]-'a'); } SAM::Build(); SAM::calc(n); for(i=1;i<=n;i++) { printf("%d\n",f[i]); } return 0; }
相關推薦
[SPOJ-NSUBSTR]Substrings
ngs root pan void 每一個 忽略 [] 後綴自動機 clu 題目大意: 給你一個字符串s,求出不同長度出現次數最多的字串的最大出現次數。 思路: 先對s構造後綴自動機,然後把s放進去匹配,每一個經過的結點表示一種長度的子串,用一個cnt記錄
Spoj NSUBSTR - Substrings
ons radius true strings ask times div iostream because 題目描述 You are given a string S which consists of 250000 lowercase latin letters at
SPOJ - NSUBSTR 後綴自動機板子
color set xtend bst air long rst span poj SPOJ - NSUBSTR #include<bits/stdc++.h> #define LL long long #define fi first #defin
SPOJ - NSUBSTR 字尾自動機板子
SPOJ - NSUBSTR #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int,
SPOJ NSUBSTR
題意: 給出一個字串,求這個字串長度為1-n的子串的最大出現次數; 字串長度<=250000; 題解: 幾天沒更新,水一發字尾自動機的題解吧; 首先定義字尾自動機的的right集合大小,就是該結點代表的狀態能拓展到的子串種類; 那麼對於長度為x的子串的答案就是所有長
SPOJ NSUBSTR(Substrings-字尾自動機統計串出現次數-Right集合&Parent樹の暴走)
8222. Substrings Problem code: NSUBSTR You are given a string S which consists of 250000 lowercase latin letters at most. We define F
●SPOJ 8222 NSUBSTR - Substrings
-- ostream 關系 .com printf light return 相關 存儲 題鏈: http://www.spoj.com/problems/NSUBSTR/ 題解: 後綴自動機的水好深啊!懂不了相關證明,帶著結論把這個題做了。看來這灘深水要以後再來了。 本
[SPOJ DQUERY] D-query(樹狀數組,離線)
vector scan con oid n) fin %d ear span 題目鏈接:https://vjudge.net/problem/SPOJ-DQUERY 題意:給定數列,q次詢問,問區間內不同數字的個數。 可以用主席樹,但是還有更好寫的辦法。 離線存下所有的詢問
SPOJ SUMPRO(數學)
strong 序列 分析 所有 枚舉 發現 個數 得到 題意 題意: 給出一個數N,問所有滿足n/x=y(此處為整除)的所有x*y的總和是多少。對答案mod(1e9+7)。 1 <= T <= 500。 1 <= N <= 1e9。 分析:
[SPOJ VLATTICE]Visible Lattice Points 數論 莫比烏斯反演
string rst ase 計算 mod visible font sample poj 7001. Visible Lattice Points Problem code: VLATTICE Consider a N*N*N lattice.
杜教篩進階+洲閣篩講解+SPOJ divcnt3
前綴 con bre sca else rac poj class algo Part 1:杜教篩進階在了解了杜教篩基本應用,如$\sum_{i=1}^n\varphi(i)$的求法後,我們看一些杜教篩較難的應用。求$\sum_{i=1}^n\varphi(i)*i$考慮把
Spoj 10628. Count on a tree
open class style pen 技術 += 初始 medium poj Description 給定一棵N個節點的樹,每個點有一個權值,對於M個詢問(u,v,k),你需要回答u xor lastans和v這兩個節點間第K小的點權。其中lastans是上一個詢
【BZOJ2780】[Spoj]8093 Sevenk Love Oimaster 廣義後綴自動機
當前 named ostream number 一個點 urn mil ios abc 【BZOJ2780】[Spoj]8093 Sevenk Love Oimaster Description Oimaster and sevenk love each
SPOJ - TSUM Triple Sums FFT+容斥
tex 分享 con size 題解 pair const ati print Triple Sums You‘re given a sequence s of N distinct integers.Consider all the possible sums o
SPOJ - AMR11H Array Diversity (水題排列組合或容斥)
div max size pen n+1 scanf 水題 brush cnblogs 題意:給定一個序列,讓你求兩種數,一個是求一個子序列,包含最大值和最小值,再就是求一個子集包含最大值和最小值。 析:求子序列,從前往記錄一下最大值和最小值的位置,然後從前往後掃一遍,每個
Spoj-BOKAM143SOU Checking cubes.
putc spl src == display pen result tput put Given a integer N. Find number of possible ways to represent N as a sum of at most five cubes
Spoj-NPC2015A Eefun Guessing Words
pla cti names memset cst fun second math spl Eefun Guessing Words Eefun is currently learning to read. His way of learning is unique, by
Spoj-BITDIFF Bit Difference
cas represent stream ted using aps ces define find Given an integer array of N integers, find the sum of bit differences in all the pairs
Spoj-ANTP Mr. Ant & His Problem
adding one exp read namespace ... using cells table Mr. Ant has 3 boxes and the infinite number of marbles. Now he wants to know the numb
Spoj-BGSHOOT
sad ive nbsp update amp eba return lib ast The problem is about Mr.BG who is a great hunter. Today he has gone to a dense forest for hunt