如果a串是另b串的字尾,那麼在trie圖上沿著b的fail指標走一定可以走到a串。
而a串在b串裡出現多少次就是它是多少個字首的字尾。
所以把fail邊反向建樹維護個dfs序就行了。
並不是很難。。。但沒想出來tat
1 #include2 #include3 #include4 #include5#define n 200005
6#define inf 0x3f3f3f3f
7using
namespace
std;
8intn;9
int ch[n][2
], fa[n];
10int
a[n];
11int
mn[n],zhi[n],size[n];
12void push_up(int
x)13
17int
rev[n];
18void push_down(int
x)19
25return;26
}27void rotate(int
p)28
38 push_up(q); return;39
}40introot;
41void splay(int x,int
yy)4251}
52push_up(x);
53if (!yy)root =x;54}
55int
cnt;
56int find(int k, int
x)57
63if (zhi[k] == x)return size[ch[k][0]] + 1;64
return find(ch[k][1], x) + size[ch[k][0]] + 1;65
}66int fd(int k, int
x)67
73struct
node
7481
}s[n];
82int
yin[n];
83int
main()
8490 sort(s+1,s+n+1
);91
for(int i=1;i<=n;i++)
9295 root = 1; a[n + 1] =inf;
96 ch[1][1] = 2; zhi[1] = a[1]; size[1] = n + 1;97
for (int i = 2; i <= n + 1; i++)
98102
for (int i = n + 1; i >= 1; i--)push_up(i);
103 splay(n, 0
);104
for (int i = 1; i <= n; i++)
105117 puts(""
);118
return0;
119 }
BZOJ 2434 阿狸的打字機
題意 回答第x個模式串在第y個模式串 現了幾次。資料範圍 n,m,q 105 sum n,sum m,q leq10 5 n m q 105顯然可以離線,對於相同y的詢問集中處理,暴跳fail的時候開個桶丟進去,最後把有用的提出來。但是還是太慢了。考慮問題本質 對於一組詢問x,y x,yx,y實際上...
2434 Noi2011 阿狸的打字機
題目鏈結 題目大意 初始字串為空,首先給定一系列操作序列,有三種操作 1.在結尾加乙個字元 2.在結尾刪除乙個字元 3.列印當前字串 然後多次詢問第x個列印的字串在第y個列印的字串中出現了幾次 題解 建出trie 新增乙個字元 新建乙個子節點 若存在在不用新建 進入該子節點 刪除乙個字元 返回到父親...
BZOJ2434 NOI2011 阿狸的打字機
發現一種新的思路,以前從來沒有見過的,即ac自動機的fail樹。這一題我們先考慮暴力,從root往y的最後乙個點走,如果走到了x的末點,ans 如果通過fail指標走到了x的末點,ans 反過來考慮,從x的末點開始,如果當前點在y串或者通過反向的fail到了y串,ans 又發把fail反向之後得到的...