首先學一波字串的一些性質。首先求出字串的字尾陣列和高度陣列之後,就可以求出這個字串有多少個不同的字串。
ps:這個字尾陣列模板為倍增+基數排序。複雜度nlog(n),基數排序o(n),倍增是log但是常數太大,.高度陣列可以利用字尾陣列o(n)求出!
#include #include #include #include #include using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=100010;
int sa[maxn];
int t1[maxn],t2[maxn],c[maxn];
int rank[maxn],lcp[maxn];
void construct_sa(char s,int n,int m)
}void construct_lcp(char s,int n)
if(flag) fvis[i]=1,pr[i]=fpr;
}ll ans=0;
construct_sa(str,n+1,128);
construct_lcp(str,n);
for(int i=0;i<=n;i++)
printf("case #%d: %i64d\n",cas++,ans);
}return 0;
}
下面這個是nlog(n)log(n)的模板,做這個題就超時了,利用的是倍增的思想,但是是普通的排序,(nlog(n)).
#include #include #include #include #include using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=100010;
int sa[maxn];
int nn;
int kk;
int rank[maxn],lcp[maxn],tmp[maxn];
bool compare_sa(int i,int j)
if(flag) fvis[i]=1,pr[i]=fpr;
}ll ans=0;
nn=n+1;
construct_sa(str,n+1);
construct_lcp(str,n);
for(int i=0;i<=n;i++)
printf("case #%d: %i64d\n",cas++,ans);
}return 0;
}
HDU 5769字尾陣列
題意 給你乙個串,問你含某個特定的字元的不同子串有多少種。思路 使用字尾陣列。很久之前看過做過幾個模板水題。以為自己做不到這麼高深的題目。結果這次就卡了,想hash莽一下發現很不科學,就放棄了。看來字尾陣列也已經是標配了。趕緊再補充補充自己。首先退一步講,字尾陣列如何求不同子串個數。其實就是利用排序...
hdu5769Substring 字尾陣列
題意 給你乙個字元x和乙個字串s,問你s中有多少個不相同的子串?且必須含有字元x。題解 1 我們可以利用字尾陣列來做這道題。我們求出我們要的三個陣列ra,sa,height。字尾陣列求出來的三個陣列 2 我們知道乙個字尾能夠貢獻出n sa i 1 height i 個不相同的子串,而我們要包含字元x...
HDU 5769 Substring 字尾陣列
傳送門 思路 不考慮x字元,先考慮怎麼求本質不同的串有幾個,那麼就是列舉一遍height陣列,去掉字首相同的就可以了。我們考慮x字元的話,就要保證所有求得的串都要包含這個字元。那麼我們事先求乙個陣列,pos i 表示當前字元 包括自身 的右邊的第乙個x字元的位置。然後還是列舉height陣列,當前字...