題意:給你乙個串,問你含某個特定的字元的不同子串有多少種。。
思路:使用字尾陣列。。很久之前看過做過幾個模板水題。。以為自己做不到這麼高深的題目。。結果這次就卡了,想hash莽一下發現很不科學,就放棄了。。看來字尾陣列也已經是標配了。。趕緊再補充補充自己。。
首先退一步講,字尾陣列如何求不同子串個數。。。其實就是利用排序的性質來解決。。假設我們得到了sa和height。。那麼我們來列舉每乙個字尾串對於答案的貢獻。。顯然不考慮重複肯定是len-sa[ i ]。。也就是總長度減去現在的位置,這個很好理解。。那麼如何去除重複呢?利用排序的性質和height的意義。。也就是排序好的相鄰的最長公共字首。。那麼我們就可以知道有多少是重複的,這樣就是len-sa[ i ]-height[ i ]。。到這裡問題基本就解決了。
回到這個題目,要包含某個特定的字元,其實如果知道每個字尾串要做出貢獻至少要多長就可以。。如果知道了,套用上面的就好啦~
ps。字尾陣列的原理還是不是很懂。。不過重在應用。。慢慢學習。。
**:
#include using namespace std;
const int maxn=200010;
int t1[maxn],t2[maxn],c[maxn];//求sa陣列需要的中間變數,不需要賦值
bool cmp(int *r,int a,int b,int l)
void da(int str,int sa,int ran,int height,int n,int m)
int k = 0;
n--;
for(i = 0; i <= n; i++)ran[sa[i]] = i;
for(i = 0; i < n; i++)
}int ran[maxn],height[maxn];
char str[maxn];
int r[maxn];
int sa[maxn];
int nxt[maxn];
int main()
long long ans=0;
for(int i=1;i<=len;i++)
printf("case #%d: %lld\n",cas++,ans);
}}
HDU5769字尾陣列,高度陣列模板
首先學一波字串的一些性質。首先求出字串的字尾陣列和高度陣列之後,就可以求出這個字串有多少個不同的字串。ps 這個字尾陣列模板為倍增 基數排序。複雜度nlog n 基數排序o n 倍增是log但是常數太大,高度陣列可以利用字尾陣列o n 求出!include include include inclu...
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陣列,當前字...