簡略題意:求兩個串長度不小於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...