ACM-ICPC 南昌网络赛F题 Megumi With String

题目描述

给一个长度为\(l\)的字符串\(S\),和关于\(x\)的\(k\)次多项式\(G[x]\).当一个字符串\(str\)是S的子串时,定义\(str\)的\(value\)值为\(G[length(str)]\),否则\(value=0\)。一个字符串的\(power\)值定义为其所有子串的\(value\)之和。每次向\(S\)末尾添加一个字符,重复\(m\)次。求每次添加字符后,一个长度为\(n\)的随机串\(T\)的\(power\)期望值。每个测试点\(Q\)组数据

  • 出现在不同位置的相同串视为\(T\)的不同子串
  • 多项式的次数不大于\(50\)

\(\sum l,\sum m,\sum k\leq 3\times10^5\)

题目链接

题解

  • 由于串是随机的,所以不适合以特定串为研究对象。因此考虑指定长度的子串的贡献。长度为\(i\)的串的贡献正比于\(S\)中长度为\(i\)的本质不同的子串个数。由于要在线添加字符,所以使用后缀自动机维护以上信息。

使用后缀自动机维护本质不同的子串个数有两种方法:

  1. 由于从源点沿转移边到达的点所经过的路径都是一个子串,所以\(f[i]=\sum _{i\rightarrow j}(f[j] + 1)\),\(f[i]\)表示从i出发的路径个数,答案为\(f[\empty]\)
  2. SAM上每一个结点都代表一个等价类,该节点包含了长度为\((longest(fa[i]),longest(i)]\)的子串,而每一个节点包含的子串都不相同。

显然,用方法2可以更方便地在插入字符时就更新\((longest(fa[i]),longest(i)]\)的子串个数变化。

\(S\)的最终长度为\(l+m\),其中长度大于\(n\)的子串不会产生贡献。所以我们处理的子串长度范围是\([1,min(l+m,n)]\),设\(N=min(l+m,n)\)

  • \(T\)的总个数为\(26^n\)

  • 长度为\(i\)的子串出现的总次数为\((n-i+1)\cdot 26^{n-i+1}\)(出现在不同位置*周围不同字符)。所以长度为\(i\)的子串对\(power\)的贡献为\(cnt_i\cdot (n-i+1)\cdot 26^{n-i+1}\cdot G[i]\)

\(cnt_i\)表示\(S\)中长度为\(i\)本质不同的子串个数

则\(E_{power}(T)=\frac{1}{26^n}\sum_{i=1}^{min(l+m,n)}cnt_i\cdot (n-i+1)\cdot 26^{n-i+1}\cdot G[i]\)

令\(H[i]=(n-i+1)\cdot 26^{n-i+1}\cdot G[i]\)

  • 由于\(H[i]\)只与\(i\)有关,因此可以预处理\(0\sim N\)的\(H\)值

因为每次只修改连续的区间,修改只有加一操作,而且求和的范围为固定的整个区间,因此可以预处理\(H[i]\)的前缀和,每次\(O(1)\)修改对应\(len\)区间的贡献,然后直接输出\(ans\)

if (fa.longest < n) ans = (0ll + ans + G[min(n, now.longest)] + P - G[fa.longest]) % P;

处理细节

  1. 处理多组数据注意后缀自动机的初始化
void init(int nn) {
memset(am[1].ch, 0, sizeof(am[0].ch));
las = cnt = 1;
n = nn;
} //insert()
memset(am[cnt].ch, 0, sizeof(am[0].ch));
  1. 单个字符的读入——来自C语言的gank

让我误以为是读不进去,换了各种方法。最后发现其实是后缀自动机的构造函数写错才导致的TLE

把代码改的面目全非

for (i = 0; i < m; ++i)	{
ch = getchar();
if (islower(ch))
AM.insert(ch);
else {
tt++;
i--;
if (tt > 4e5)
return 0;
continue;
}
printf("%d\n", (int)(1ll * ans * inv % P));
}

最后全部改回去了。

AC代码

#include <iostream>
#include <cstring> using namespace std;
const int maxn = 2e5 + 1, P = 998244353, v26 = 729486258, sigma_size = 26; //v26=inv(26)
int G[maxn + 1], N, a[51], ans;
char S[100001]; int fexp(int x, int n) {
int ret = 1;
while (n) {
if (n & 1) ret = 1ll * ret * x % P;
x = 1ll * x * x % P;
n >>= 1;
}
return ret;
}
void getG(int len, int n, int K) {
int n26 = fexp(26, n);
G[0] = 0;
for (int i = 1; i <= len; ++i) {
int ans = 0, x = 1;
n26 = 1ll * n26 * v26 % P;
for (register int j = 0; j <= K; ++j) {
ans = (1ll * x * a[j] % P + ans) % P;
x = 1ll * x * i % P;
}
G[i] = ans;
G[i] = (1ll * G[i] * (n - i + 1) %P * n26 %P + G[i - 1]) % P;
}
return;
} struct SAM {
struct Node {
int longest, fa;
int ch[sigma_size];
Node() {
memset(ch, 0, sizeof(ch));
longest = 0;
}
}am[maxn << 1];
int las = 1, cnt = 1, n;
void init(int nn) {
memset(am[1].ch, 0, sizeof(am[0].ch));
las = cnt = 1;
n = nn;
}
void insert(int c) {
int p = las, np = ++cnt;
memset(am[np].ch, 0, sizeof(am[0].ch));
las = np;
am[np].longest = am[p].longest + 1;
for (; p && !am[p].ch[c]; p = am[p].fa) am[p].ch[c] = np;
if (!p) am[np].fa = 1;
else {
int q = am[p].ch[c];
if (am[q].longest == am[p].longest + 1) am[np].fa = q;
else {
int nq = ++cnt;
am[nq] = am[q];
am[np].fa = nq;
am[nq].longest = am[p].longest + 1;
am[q].fa = nq;
for (; p && am[p].ch[c] == q; p = am[p].fa) am[p].ch[c] = nq;
}
} if (am[am[np].fa].longest < n)
ans = (0ll + ans + G[min(n, am[np].longest)] + P - G[am[am[np].fa].longest]) % P; }
}AM;
int main() {
int Q, l, m, K, i, n, inv;
char ch;
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
cin>>Q;
while (Q--) {
cin>>l>>K>>n>>m;
N = min(l + m, n);
ans = 0;
AM.init(n);
inv = fexp(fexp(26, n), P - 2); cin>>S;
for (i = 0; i <= K; ++i)
cin>>a[i];
getG(N, n, K);
for (int j = 0; j < l; ++j) AM.insert(S[j]);
cout<<(1ll * ans * inv % P)<<endl; for (i = 0; i < m; ++i) {
cin>>ch;
AM.insert(ch);
cout<<(1ll * ans * inv % P)<<endl;
}
}
return 0;
}

ACM-ICPC 2019南昌网络赛F题 Megumi With String的更多相关文章

  1. ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval

    ACM-ICPC 2019南昌网络赛I题 Yukino With Subinterval 题目大意:给一个长度为n,值域为[1, n]的序列{a},要求支持m次操作: 单点修改 1 pos val 询 ...

  2. [2019上海网络赛F题]Rhyme scheme

    题目链接 题意,求出合法的长度为n的字典序第k小字符串,合法的定义为除了最后一位,每一位的取值范围为'A'到'A'+pos-1,而最后一位的取值范围'A'到当前字符串最大值+1. 队友tql,Orz ...

  3. 2019南昌网络赛I:Yukino With Subinterval(CDQ) (树状数组套主席树)

    题意:询问区间有多少个连续的段,而且这段的颜色在[L,R]才算贡献,每段贡献是1. 有单点修改和区间查询. 思路:46min交了第一发树套树,T了. 稍加优化多交几次就过了. 不难想到,除了L这个点, ...

  4. ICPC 2019 徐州网络赛

    ICPC 2019 徐州网络赛 比赛时间:2019.9.7 比赛链接:The Preliminary Contest for ICPC Asia Xuzhou 2019 赛后的经验总结 // 比赛完才 ...

  5. Magic Master(2019年南昌网络赛E题+约瑟夫环)

    目录 题目链接 题意 思路 代码 题目链接 传送门 题意 初始时你有\(n\)张牌(按顺序摆放),每一次操作你将顶端的牌拿出,然后按顺序将上面的\(m\)张牌放到底部. 思路 首先我们发下拿走\(1\ ...

  6. 2013 ACM/ICPC 长春网络赛F题

    题意:两个人轮流说数字,第一个人可以说区间[1~k]中的一个,之后每次每人都可以说一个比前一个人所说数字大一点的数字,相邻两次数字只差在区间[1~k].谁先>=N,谁输.问最后是第一个人赢还是第 ...

  7. 2013 ACM/ICPC 南京网络赛F题

    题意:给出一个4×4的点阵,连接相邻点可以构成一个九宫格,每个小格边长为1.从没有边的点阵开始,两人轮流向点阵中加边,如果加入的边构成了新的边长为1的小正方形,则加边的人得分.构成几个得几分,最终完成 ...

  8. 2019 ICPC南昌网络赛 B题

    英雄灭火问题忽略了一点丫 一个超级源点的事情,需要考虑周全丫 2 #include<cstdio> #include<cstring> #include<queue> ...

  9. 2019 ICPC南京网络赛 F题 Greedy Sequence(贪心+递推)

    计蒜客题目链接:https://nanti.jisuanke.com/t/41303 题目:给你一个序列a,你可以从其中选取元素,构建n个串,每个串的长度为n,构造的si串要满足以下条件, 1. si ...

随机推荐

  1. C语言笔试

    1.一个C程序的执行时从本程序的main开始,到main结束. 2.C语言规定else总是与在其之前的未配对的最近if配对. 3.int型数据在内存中的存储形式是补码. 4.数组一旦定义其大小是固定的 ...

  2. How to add Facebook’s Customer Chat Plugin to your website

    How to add Facebook’s Customer Chat Plugin to your website By Gerardo Salandra  Do you need a live c ...

  3. 解决zabbix中文乱码问题

    进入Windows系统控制面板-->外观和个性化-->字体(选择一个字体文件simsun.ttc复制)进入zabbix的web服务器[root@test-zabbix]# cd ~/zab ...

  4. TCP为什么要三次握手?

    在<计算机网络>一书中其中有提到,三次握手的目的是“为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误”,这种情况是: 一端(client)A发出去的第一个连接请求报文并没有丢 ...

  5. 使用请求包装器RequestWrapper 对博客内容进行编码

    1.写一个文章类 代码如下 package model; public class article { private int id; private String title; private St ...

  6. Mysql解析json字符串/数组

    1 Mysql解析json字符串  解决方法:JSON_EXTRACT(原字段,'$.json字段名') 执行SQL: SELECT JSON_EXTRACT( t.result,'$.row'), ...

  7. # localhost 、217.0.0.1 、本机IP

    localhost .217.0.0.1 .本机IP localhost是一个域名,性质跟 "www.baidu.com" 差不多,指向127.0.0.1这个IP地址,在windo ...

  8. Java学习总结一 数据类型

    @Java300 学习总结 一.Java 基本数据类型分类如下: 整型变量:byte.short.int.long 浮点型变量:float.double 字符型变量:char 布尔型变量:boolea ...

  9. linux内核exec过程

    简介 本文分析linux内核exec系统调用执行过程中可执行文件的加载过程和栈的设置,内核代码版本为2.6.32 分析 \arch\ia64\kernel\process.c中有sys_exec函数的 ...

  10. 13.lsof恢复删除的文件

    [root@temp ~]# lsof -p 5643COMMAND  PID   USER   FD   TYPE DEVICE  SIZE/OFF    NODE NAMEoracle  5643 ...