Brief description:
给定一段 Text、以及 nn 个 Pattern。要求这个 Text 中合法的子串数目,使得对于第 ii 个 Pattern,恰好能够匹配 [l_ii, r_ii] 之间次。
(nn ≤ 10)
Analysis:
SAM-DP。
我们把涉及到的所有字符串(Text && Patterns),依次插入到 SAM。(相邻的字符串之间,用彼此不同的分隔符隔开,以保证各字符串之间在 SAM 中不会相互干扰)
dp[ii][u] 表示:结点 u 所表示的子串集合,对于第 ii 个字符串的匹配次数。
http://codeforces.com/contest/316/submission/4749994
namespace SAM{
const int SN = int(5e4) + 1, NN = 11, N = 2*NN*SN + 9, Z = 26;
int trans[N][Z+NN], fail[N], len[N], tail, tot; char str[SN];
inline int new_node(){
// RST(trans[tot);
tail = tot;
return tot++;
}
inline int new_node(int u){
CPY(trans[tot], trans[u]), fail[tot] = fail[u];
return tot++;
}
#define v trans[u][c]
#define f fail[u]
#define ff fail[uu]
inline int h(int u){
return len[u] - len[f];
}
void Ext(int c){
int u = tail, uu = new_node(); len[uu] = len[u] + 1;
while (u && !v) v = uu, u = f;
if (!u && !v) v = uu, ff = 0;
else{
if (len[v] == len[u] + 1) ff = v;
else{
int _v = v, vv = new_node(_v); len[vv] = len[u] + 1;
fail[_v] = ff = vv;
while (v == _v) v = vv, u = f;
}
}
}
int dp[NN][N], l[NN], r[NN]; bool vis[N];
int nn, ans;
#define c (*cur - 'a')
void Init(){
tot = 0, new_node();
gets(str); REP_S(cur, str) Ext(c); Ext(Z);
REP_1_C(ii, RD(nn)){
RS(str); RD(l[ii], r[ii]);
REP_S(cur, str) Ext(c); Ext(Z+ii);
}
}
#undef c
inline bool legal(int u){
if (!u || !dp[0][u]) return 0;
REP_1(ii, nn) if (dp[ii][u] < l[ii] || r[ii] < dp[ii][u]) return 0;
return 1;
}
void dfs(int u = 0){
if (vis[u]) return; vis[u] = 1;
REP(ii, nn+1) if (trans[u][Z+ii]) dp[ii][u] = 1;
REP(c, Z) if (v){
dfs(v); REP(ii, nn+1) dp[ii][u] += dp[ii][v];
}
if (legal(u)) ans += h(u);
}
} using namespace SAM;
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
Init(); dfs(); OT(ans);
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
