题意:给定字符串,求每个前缀的本质不同的子串数量。字符集1e9。

解:在线构造后缀自动机并统计答案。

答案就是∑len[i] - len[fail[i]]

每次增加的时候,至多对三个节点有影响。然而把Q分裂为nQ本质不同的子串数没变。

于是增加的只有len[np] - len[fail[np]]

map维护转移边。

 #include <cstdio>
#include <map> typedef long long LL;
const int N = ; int len[N], fail[N], last, top;
LL ans;
std::map<int, int> mp[N]; inline void init() {
top = last = ;
return;
} inline void insert(int f) {
int p = last, np = ++top;
last = np;
len[np] = len[p] + ;
while(p && !mp[p].count(f)) {
mp[p][f] = np;
p = fail[p];
}
//printf("p = %d \n", p);
if(!p) {
fail[np] = ;
ans += len[np];
//printf("1 : ans += %d \n", len[np]);
}
else {
int Q = mp[p][f];
//printf("Q = %d \n", Q);
if(len[Q] == len[p] + ) {
fail[np] = Q;
ans += len[np] - len[Q];
//printf("2 : ans += %d \n", len[np] - len[Q]);
}
else {
int nQ = ++top;
len[nQ] = len[p] + ;
fail[nQ] = fail[Q];
fail[Q] = fail[np] = nQ;
mp[nQ] = mp[Q];
while(mp[p].count(f) && mp[p][f] == Q) {
mp[p][f] = nQ;
p = fail[p];
}
ans += len[np] - len[nQ];
}
}
return;
} int main() {
int n;
scanf("%d", &n);
init();
for(int i = , x; i <= n; i++) {
scanf("%d", &x);
insert(x);
printf("%lld\n", ans);
} return ;
}

AC代码

洛谷P4070 生成魔咒的更多相关文章

  1. 洛谷 P4070 [SDOI2016]生成魔咒 解题报告

    P4070 [SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 \(1\).\(2\) 拼凑起来形成一个魔咒串 \([1,2]\). 一个魔咒 ...

  2. P4070 [SDOI2016]生成魔咒

    题目地址:P4070 [SDOI2016]生成魔咒 相信看到题目之后很多人跟我的思路是一样的-- 肯定要用 SA(P3809 [模板]后缀排序) 肯定要会求本质不同的子串个数(P2408 不同子串个数 ...

  3. bzoj4516 / P4070 [SDOI2016]生成魔咒

    P4070 [SDOI2016]生成魔咒 后缀自动机 每插入一个字符,对答案的贡献为$len[last]-len[fa[last]]$ 插入字符范围过大,所以使用$map$存储. (去掉第35行就是裸 ...

  4. 【LG4070】[SDOI2016]生成魔咒

    [LG4070][SDOI2016]生成魔咒 题面 洛谷 题解 如果我们不用在线输的话,那么答案就是对于所有状态\(i\) \[ \sum (i.len-i.fa.len) \] 现在我们需要在线询问 ...

  5. BZOJ4516: [Sdoi2016]生成魔咒 后缀自动机

    #include<iostream> #include<cstdio> #include<cstring> #include<queue> #inclu ...

  6. BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]

    4516: [Sdoi2016]生成魔咒 题意:询问一个字符串每个前缀有多少不同的子串 做了一下SDOI2016R1D2,题好水啊随便AK 强行开map上SAM 每个状态的贡献就是\(Max(s)-M ...

  7. [SDOI2016]生成魔咒

    题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1, ...

  8. BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay

    BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...

  9. [BZOJ 4516] [SDOI 2016] 生成魔咒

    Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例 ...

随机推荐

  1. Angular 基本指令

    <!DOCTYPE html><html ng-app><head lang="en"> <meta charset="UTF- ...

  2. jq简单仿上传文件

    html: <div> <input id="lefile" type="file" style="display:none&quo ...

  3. K3CLOUD常用数据表

    一.数据库查询常用表 --查询数据表select * from ( select convert(varchar(4000),t1.FKERNELXML.query('//TableName')) a ...

  4. Java 线程的创建和启动

    Java 使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例.每个线程的作用是完成一定的任务,实际上就是执行一段程序流(一段顺序执行的代码). Java 使用线程执 ...

  5. cordova微信支付回调App闪退

    这是cordova版本太高,不兼容这个插件所导致的.解决方案是修改$your_project/plugins/cordova-plugin-wechat/scripts/android-install ...

  6. python之tips(三)--为什么Python有相同的不可变对象id不同?

    参考 : https://www.jianshu.com/p/0f6f0db0ce8f

  7. Yii2控制台命令

    Yii2控制台表格输出: 例如: $in_sheet_number_queue = []; $wms_material_in_sheet_list = \core\models\WmsMaterial ...

  8. vue自定义组件及传值

    1.使用 Vue.component() 方法注册组件 2.使用 props 属性传递参数 v-for="item in items": 遍历 Vue 实例中定义的名为 items ...

  9. LODOP设置判断后执行哪个

    LODOP的语句是普通的语句,可以通过JS判断确定要执行哪个,或通过循环循环执行一些语句.如果需要执行某些打印项在哪些条件下不打印,不需要通过代码删除打印项,类似LODOP.SET_PRINT_STY ...

  10. C 语言----- 指针

    指针是一个值为内存地址的变量, 指针的核心是它是一个变量, 只不过它是用来存放内存地址的, 所以在了解指针之前,先说一下什么是变量.变量就是在内存中开辟的一个空间.如int year, 就是在内存中开 ...