HDU 5769 Substring 字尾陣列

2021-07-22 02:26:46 字數 1512 閱讀 6391

傳送門:

思路:不考慮x字元,先考慮怎麼求本質不同的串有幾個,那麼就是列舉一遍height陣列,去掉字首相同的就可以了。

我們考慮x字元的話,就要保證所有求得的串都要包含這個字元。那麼我們事先求乙個陣列,pos[i]表示當前字元(包括自身)的右邊的第乙個x字元的位置。然後還是列舉height陣列,當前字尾沒有x字元就continue。如果當前的height==0的話,說明跟前面的沒有字首相同,就是直接len-pos[sa[i]]。然後height!=0的時候,就要看這個x字元在什麼位置,如果在公共字首內的話就可以不包括這個字首了,因為前面求過了,就是len-sa[i]-height[i]。如果在公共字首外,說明這個沒有求過,就是len-pos[sa[i]]。

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

typedef long long ll;

typedef pair pii;

#define pb push_back

#define mp make_pair

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

#define calm (l+r)>>1

const int inf = 2139062143;

const int maxn=3e5+10;

struct sa

int c12(int k,int

*r,int a,int b)

void sort(int

*r,int

*a,int

*b,int n,int

m) void dc3(int

*r,int

*sa,int n,int

m) void calheight(int

*r,int

*sa,int n)

}rst;

char str[maxn];

int r[maxn],sa[maxn],pos[maxn];

int case;

char t[2];

ll cal(int len)

else

}return ans;

}int main()

pos[i]=p;

}if(p==-1)printf("case #%d: 0\n",++case);

else

printf("case #%d: %i64d\n",++case,cal(len));

}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(字尾陣列)

求字串 s 本質不同且一定包含字元 x 的子串個數。1 leq s leq 10 5 求乙個長度為 n 的串 s 本質不同的子串個數可以使用公式 displaystyle sum n sa i 1 h i 其中 h 0 1 這個公式是比較好證的。字尾的字首就是子串,我們分析每個字尾有多少個對答案有貢...