DAY 8

今日得分:2+10+4

(今天的T1和T3是原题,然而我并没做过,惨遭毒瘤。。。)(不过好像大家也没太写)

(话说好像真正实现起来并没有太过毒瘤)

T1

题目大意:给你一个长度为L的字符串s0,字符集大小为2n,q次操作,A操作表示在第f个字符串s[f]后面接上一个字符x,得到一个最新的s,Q操作询问第f个字符串s[f],目前有一个字符串t已经匹配到了l,每次随机在t后面添加一个字符,期望添加多少字符使得s[f]能够作为t的子串出现mod998244353,强制在线。n,q,L<=3e5。

题解:

定义题目所求为E(s,l),通过生成函数可以证明以下式子(具体证明参考CTSC2006歌唱王国):

注意到[s[1…i]=s[n-i+1…n]]等价于1-i是s的border,于是我们考虑KMP。由于每次增加一个字符,我们可以看成在原来的结构上添加一个新节点,从而动态构建操作树。通过倍增算法可以记录每一个点的next[i]的深度以及对应链上第next[i]+1个字符,这样的话除去KMP部分的复杂度是O(NlogN)。至于KMP部分,我们考虑我们寻找next指针时,其实质相当于构建出每个点的KMP自动机,每次添加一个新字符,先通过原串的自动机找到next节点,把它的所有转移边拷贝过来,并更改一条对next节点本身的转移边,用主席树即可做到O(logn)复杂度转移。所以总时间复杂度是O(NlogN)的。

(话说为啥我写的O(nlogn)还没O(nlog^2n)跑得快啊,哭了)

AC代码:
 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
inline int re_ad()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=x*10+(ch^
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值