洛谷P3181 字尾陣列

2022-05-20 01:42:45 字數 2364 閱讀 6299

題目要求求出兩個兩個字串中相同子串的方案數,那麼我們將其拼接起來,去求出拼接後的字串中含有相同子串的數量。

當然這樣做會求出同乙個字串中相同子串的數量,所以我們還需要如法炮製分別求出兩個字串中的答案,然後用總貢獻減去他們。

那麼問題就變成了如何求出乙個字串中相同子串的數量。

實際上這就是求任意兩個字尾x,y的lcp(x,y)和,利用字尾陣列,可以知道任意兩個lcp(x,y)為min x <= i <= y

所以說問題在利用字尾陣列求出height陣列之後轉化為了如何求height所有子區間內最小值的和。

事實上這是乙個經典的利用dp做的問題,求解乙個序列中任意子區間的最小值的和,設定l[i]表示最左端的大於a[i]的下標,r[i]表示最右端的大於等於a[i]的下標,注意需要左閉右開,然後在求出來之後對於每個位置,對答案的貢獻就是 a[i] * (i - l[i] + 1) * (r[i] - i + 1)

注意事項:在拼接字串的過程中,需要在兩字串中間增加乙個'z' + 1的字元,防止出現取到的相同子串跨越兩個被拼接的字串

#include #include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define for(i, x, y) for(int i=x;i<=y;i++)

#define _for(i, x, y) for(int i=x;i>=y;i--)

#define mem(f, x) memset(f,x,sizeof(f))

#define sca(x) scanf("%d", &x)

#define sca2(x,y) scanf("%d%d",&x,&y)

#define sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)

#define scl(x) scanf("%lld",&x)

#define pri(x) printf("%d\n", x)

#define prl(x) printf("%lld\n",x)

#define clr(u) for(int i=0;i<=n;i++)u[i].clear();

#define ll long long

#define ull unsigned long long

#define mp make_pair

#define pii pair#define pil pair#define pll pair#define pb push_back

#define fi first

#define se second typedef vector

vi;int read()

while (c >= '

0'&&c <= '

9')return x*f;}

const

double pi = acos(-1.0

);const

double eps = 1e-9

;const

int maxn = 4e5 + 10

;const

int inf = 0x3f3f3f3f

;const

int mod = 1e9 + 7

;const

int sp = 20

; int

m,k,l1,l2,l;

char

str[maxn];

intsa[maxn],rak[maxn],tex[maxn],tp[maxn],height[maxn];

void qsort(int

n)void sa(char *str,int

n) }

}void getheight(char *str,intn)}

ll l[maxn],r[maxn];

ll work(

int* a,int

n)

for(int i = n; i >= 1; i --)

ll ans = 0

;

for(int i = 1; i <= n ; i ++)

return

ans;

}int

main()

洛谷 P3809 模板 字尾排序 字尾陣列

題目描述 讀入乙個長度為 n n 的由大小寫英文本母或數字組成的字串,請把這個字串的所有非空字尾按字典序從小到大排序,然後按順序輸出字尾的第乙個字元在原串中的位置。位置編號為 1 1 到 n n 輸入輸出格式 輸入格式 一行乙個長度為 n n 的僅包含大小寫英文本母或數字的字串。輸出格式 一行,共n...

洛谷P3809 字尾排序 字尾陣列 模板

這是一道模板題。讀入乙個長度為 nn 的由大小寫英文本母或數字組成的字串,請把這個字串的所有非空字尾按字典序從小到大排序,然後按順序輸出字尾的第乙個字元在原串中的位置。位置編號為 11 到 nn。輸入格式 一行乙個長度為 nn 的僅包含大小寫英文本母或數字的字串。輸出格式 一行,共n個整數,表示答案...

洛谷P3809(字尾陣列模板題)

p3809 思路 使用字尾陣列以o nlogn 的複雜度將所有字尾陣列的字典序大小求出即可。字尾陣列 include include include includeusing namespace std const int maxn 4e6 10 ss陣列表示將要輸入的字串陣列 char ss ma...