POJ 3415 字尾陣列 單調棧

2021-08-08 03:11:31 字數 1607 閱讀 3069

簡略題意:求兩個串長度不小於k的公共子串的個數。

我喜歡這題!

首先按height分組,隨後對於每個a字尾,看之前出現的b字尾與其的lcp,若其長度為

x ,則對答案的貢獻為x−

k+1。暴力查詢n2

, 其實b字尾的排名越接近當前a字尾,兩者的lcp越高 想一想,為什麼, 因此維護乙個單調棧,以及棧內元素貢獻總和。顯然從棧底到棧頂元素逐漸增大。對a統計完答案之後再對b統計一次即可。

#include 

#include

#include

#include

#include

#include

using namespace std;

typedef long

long ll;

const ll n = 220000;

ll n, k;

char

str[n], str2[n];

ll f = 0;

namespace sa

s1[y = x] = ch;

}if (ch+1

< n1) sais(n1, ch+1, s1, t+n, p+n1);

else

for (ll i = 0; i < n1; i++) sa[s1[i]] = i;

for (ll i = 0; i < n1; i++) s1[i] = p[sa[i]];

inducedsort(s1);

}templatell mapchartoll(ll n, const t *str)

templatevoid suffixarray(ll n, const t *str)

}void rmq_init()}}

ll rmq(ll l, ll r)

ll lcp(ll i, ll j)

void init(char *str)

ll stk[n], count[n], top;

void solve(ll k, ll pos)

ll cnt = 0;

while(top && stk[top] > height[i])

if(sa[i-1] < pos) else

if(cnt)

stk[++top] = height[i], count[top] = cnt, sum += (stk[top] - k + 1)*count[top];

if(sa[i] > pos)

ans += sum;

}top = sum = 0;

for(ll i = 2; i <= n; i++)

ll cnt = 0;

while(top && stk[top] > height[i])

if(sa[i-1] > pos) else

if(cnt)

stk[++top] = height[i], count[top] = cnt, sum += (stk[top] - k + 1)*count[top];

if(sa[i] < pos)

ans += sum;

}coutreturn

0;}

poj 3415 字尾陣列 單調佇列

common substrings time limit 5000ms memory limit 65536k total submissions 8106 accepted 2688 description a substring of a string t is defined as t i,k...

POJ 3415 字尾陣列

題意 給定2個串 a串和b串 求兩個串公共子串長度大於等於k的個數。思路 首先是兩個字串的問題。所以想用乙個 把兩個字串拼接起來。求字尾陣列。然後按照k把height陣列分組。大於等於k的為一組,然後就是統計每組的貢獻。對於每一組的貢獻即是組內所有a串的字尾和b串的字尾的lcp值,即為val.那麼v...

POJ 3415 字尾陣列 單調棧 並查集

題意 傳送門 poj 3415 題解子串是原串中連續的一段,也可以定義為字首的字尾或字尾的字首。統計分別屬於 a,b a,ba,b 的不小於 k kk 的子串個數,那麼將 a,b a,ba,b 用乙個不屬於這兩個串的字元拼接起來 避免拼接位置對結果產生影響 構造字尾陣列以及高度陣列 lcp i lc...