P2336 [SCOI2012]喵星球上的点名

P2336 [SCOI2012]喵星球上的点名(AC 自动机 + BIT + dfn 序 + LCA )

这道题除了 AC 自动机中 Fail 树本身的性质,与其他题目最大不同是它 AC 自动机的建立。

这道题的字符集特别大,所以我们不能和以前一样直接存下来,于是可以想到用 Map 维护每个点可以到达的点集。

其他的区别不大,有三个地方要注意:

\(1.\) 对于一个喵星人,既有名又有姓,怎么统计呢?

直接把两个拼在一起然后搞一个间隔符就可以了。

\(2.\) 题目第一问要求不重复,于是和之前那道题一样,删除贡献即可。

\(3.\) Fail 树的构建(暂时不知道复杂度)

for(register mit it=t[0].son.begin();it!=t[0].son.end();it++) q[++r]=it->second,fail(it->second)=0;
while(l<=r){
	int now=q[l];l++;
	for(register mit it=t[now].son.begin();it!=t[now].son.end();it++){
		int Fail=fail(now),val=it->first;
		while(Fail and !son(Fail,val)) Fail=fail(Fail);
		fail(it->second)=son(Fail,val);
		q[++r]=it->second;
	}
}
for(register int i=1;i<=node_cnt;i++) Add_Edge(fail(i),i);

然后这道题第一问就是让我们统计子树和,单点修改,第二问和上一题几乎一样,单点子树修改,然后单点查询即可。

最后这篇题解讲的不错,还看不懂可以看这个。

posted @ 2021-04-19 20:10  __Anchor  阅读(78)  评论(0编辑  收藏  举报