luogu4770 [NOI2018]你的名字 后缀自动机 + 线段树合并

1326433-20181127215714033-72785805.png


其实很水的一道题吧....

题意是:每次给定一个串\(T\)以及\(l, r\),询问有多少个字符串\(s\)满足,\(s\)\(T\)的子串,但不是\(S[l .. r]\)的子串


统计\(T\)本质不同的串,建个后缀自动机

然后自然的可以想到,对于每个\(T\)的子串,它对应了一个\(right\)集合

那么,它应该会被这个\(right\)集合所限制

考虑对于每个\(i\),求出最小的\(l\)使得\(T[l .. i]\)存在于\(S[l..r]\)

这个可以套个线段树转移

然后就没了.....


如果不需要统计\(T\)本质不同的串,又怎么做呢?

统计的时候乘上\(right\)集合大小就行


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;#define ri register int
#define ll long long
#define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
#define drep(io, ed, st) for(ri io = ed; io >= st; io --)#define gc getchar
inline int read() {int p = 0, w = 1; char c =  gc();while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();return p * w;
}const int sid = 1005000;
const int eid = 30000000 + 5;struct SAM {int id, fa[sid], mx[sid];int go[sid][26], mc[sid];inline int newnode() {++ id;fa[id] = mx[id] = mc[id] = 0;memset(go[id], 0, sizeof(go[id]));return id;}inline void init() {id = 0;newnode();}inline int extend(int lst, int c, int pos) {int np = newnode(), p = lst;mx[np] = mx[p] + 1; mc[np] = pos;for( ; p && !go[p][c]; p = fa[p]) go[p][c] = np;if(!p) fa[np] = 1;else {int q = go[p][c];if(mx[p] + 1 == mx[q]) fa[np] = q;else {int nq = newnode(); mx[nq] = mx[p] + 1;fa[nq] = fa[q]; fa[np] = fa[q] = nq;memcpy(go[nq], go[q], sizeof(go[q]));for( ; p && go[p][c] == q; p = fa[p]) go[p][c] = nq;}}return np;}} S, T;int q, n, m, seg;
char s[sid], t[sid];
int nc[sid], ip[sid], w[sid], val[sid];
int rt[sid], ls[eid], rs[eid];inline int merge(int x, int y) {if(!x || !y) return x + y;int o = ++ seg;ls[o] = merge(ls[x], ls[y]);rs[o] = merge(rs[x], rs[y]);return o;
}inline void ins(int &o, int l, int r, int p) {o = ++ seg;if(l == r) return;int mid = (l + r) >> 1;if(p <= mid) ins(ls[o], l, mid, p);else ins(rs[o], mid + 1, r, p);
}inline bool qry(int o, int l, int r, int ml, int mr) {if(ml > r || mr < l || ml > mr || !o) return 0;if(ml <= l && mr >= r) return 1;int mid = (l + r) >> 1;if(qry(ls[o], l, mid, ml, mr)) return 1;else return qry(rs[o], mid + 1, r, ml, mr);
}inline void init() {S.init();int lst = 1;rep(i, 1, n) lst = S.extend(lst, s[i] - 'a', i);int id = S.id;rep(i, 1, id) nc[S.mx[i]] ++;rep(i, 1, n) nc[i] += nc[i - 1];rep(i, 1, id) ip[nc[S.mx[i]] --] = i;rep(i, 1, id) if(S.mc[i]) ins(rt[i], 1, n, S.mc[i]);drep(i, id, 1) {int o = ip[i], f = S.fa[o];rt[f] = merge(rt[f], rt[o]);}
}void Match(int l, int r) {int o = 1, nl = 0;rep(i, 1, m) {int c = t[i] - 'a';while(1) {int nxt = S.go[o][c], f = S.fa[o];if(nxt && qry(rt[nxt], 1, n, l + nl, r)) {nl ++; o = nxt;break;}if(!nl) break; nl --;if(nl == S.mx[f]) o = f;}w[i] = nl;}
}int main() {scanf("%s", s + 1);n = strlen(s + 1);init(); q = read();rep(i, 1, q) {scanf("%s", t + 1);m = strlen(t + 1);T.init();int lst = 1;rep(j, 1, m) lst = T.extend(lst, t[j] - 'a', j);int l = read(), r = read();Match(l, r);int id = T.id;rep(i, 1, id) nc[i] = val[i] = 0;rep(i, 1, id) nc[T.mx[i]] ++;rep(i, 1, id) nc[i] += nc[i - 1];rep(i, 1, id) ip[nc[T.mx[i]] --] = i;drep(i, id, 1) {int o = ip[i], f = T.fa[o];if(T.mc[o]) val[o] = w[T.mc[o]];val[f] = max(val[f], val[o]);}ll ans = 0;rep(i, 1, id) ans += max(T.mx[i] - max(T.mx[T.fa[i]], val[i]), 0);printf("%lld\n", ans);}return 0;
}

转载于:https://www.cnblogs.com/reverymoon/p/10029355.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364796.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

团队计划会议

跟航哥想了挺多要做什么&#xff0c;要完成什么&#xff0c;以什么为主要功能 提出了几个想法&#xff0c;并做了投票 最后决定一起做一个跑腿软件 最初的任务量&#xff1a; 跟航哥商量两个人一人负责两个模块 航哥负责管理员和下单 我负责接单跟其他琐碎的小功能 呐&#xff…

vue.js java php_准吗?Java程序员喜欢AngularJS,PHP程序员喜欢Vue.js!

编程语言与框架或者库之间有联系是很正常的事情&#xff0c;如果我们告诉你&#xff0c;使用某一种编程语言或技术的开发人员可能更喜欢某个框架&#xff0c;你会作何反应呢&#xff1f;Stack Overflow根据网站内最常访问的标签将开发人员分为多个组&#xff0c;并检查了每组每…

结构化日志:出错时你最想要的好朋友

目录 介绍什么是日志&#xff1f;Grab中日志的状况为什么改变&#xff1f;结构化日志支持不同格式的多写开发中类似生产环境的日志因果顺序但为什么要结构化记日志&#xff1f;原文&#xff1a;Structured Logging: The Best Friend You’ll Want When Things Go Wrong 介绍 在…

在vue项目中添加特殊字体

这里的特殊字体&#xff0c;指的是一般用户电脑未安装到本地的字体&#xff0c;要引入这样的字体&#xff0c;首先需要把字体文件下载下来。 就像上图这样的&#xff0c;ttf格式的&#xff0c;然后在项目里添加它。 然后我们在font.css里用font-face规则引入这个字体文件并命名…

使用Spring WS创建合同优先的Web服务

1引言 本文介绍了如何使用来实现和测试SOAP Web服务 Spring Web Services项目 。 本示例使用JAXB2进行&#xff08;取消&#xff09;编组。 为了开发服务&#xff0c;我将使用合同优先的方法&#xff0c;该方法首先定义服务合同&#xff0c;然后基于该合同实施服务。 本文分为…

转载 Net多线程编程—System.Threading.Tasks.Parallel

.Net多线程编程—System.Threading.Tasks.Parallel System.Threading.Tasks.Parallel类提供了Parallel.Invoke&#xff0c;Parallel.For&#xff0c;Parallel.ForEach这三个静态方法。 1 Parallel.Invoke 尽可能并行执行所提供的每个操作&#xff0c;除非用户取消了操作。 方法…

Fiddler教程--简介

1、开发环境host配置自己修改系统的host来回挺麻烦的 2、前后的接口调试 3、线上bugfix 4、性能分析和优化 5.等等... 工作原理 一个代理服务器地址改为 127.0.0.1:8888流模式边走边返回缓冲模式http请求完成所有的数据之后&#xff0c;才返回 界面功能介绍 1.工具栏 从下图红色…

跟面向对象卯上了,看看ES6的“类”

上回我们说到ES5的面向对象&#xff0c;以及被大家公认的最佳的寄生组合式继承。时代在进步&#xff0c;在ES6中对于面向对象这个大boss理所应当地进行了一次大改&#xff0c;从原先那种比较长的写法转变为“小清新”写法。我们一起来看一下。 在ES6中是有类这个概念&#xff0…

Java 8中的5个功能将改变您的编码方式

Java 8在JVM和语言级别都包含了一些非常令人兴奋的功能。 虽然最初为该发行版设想的某些功能已扩大范围或已推出到第9版&#xff0c;但实际上有数十个新功能。 许多新添加的内容在编译器&#xff0c;JVM或帮助系统级别都进行了后台改进。 这样&#xff0c;虽然我们可能会从中受…

Java相关资料分享(视频+电子书籍)

关注微信公众号【Java典籍】&#xff0c;获取百度网盘提取码 ▼微信扫一扫下图↓↓↓二维码关注 转载于:https://www.cnblogs.com/bingyimeiling/p/10279049.html

vue项目 一行js代码搞定点击图片放大缩小

一行js代码搞定xue项目需要点击图片放大缩小&#xff0c;其实主要用的是用到了vue:class的动态切换&#xff0c;内容比较简单。一开始我把维护的需求想得太复杂了&#xff0c;和测试小姐姐聊了一下才反应过来。 两个月不到跟了四个项目&#xff0c;现在是维护改bug阶段&#x…

指针系统学习8-小结

1.有关指针的数据类型的小结 2.指针运算小结 一、指针变量加&#xff08;减&#xff09;一个整数,会指向上&#xff08;下&#xff09;1&#xff08;i&#xff09;个元素  例如&#xff1a;&#xff50;&#xff0b;&#xff0b;、&#xff50;&#xff0d;&#xff0d;、&am…

Spring集成–使用RMI通道适配器

1.引言 本文介绍了如何使用Spring Integration RMI通道适配器通过RMI发送和接收消息。 它由以下部分组成&#xff1a; 实施服务&#xff1a;第一部分着重于创建和公开服务。 实现客户端&#xff1a;显示如何使用MessagingTemplate类调用服务。 抽象SI逻辑&#xff1a;最后&a…

jquery点击非div区域隐藏div

点击非div区域隐藏div&#xff0c;如图&#xff0c;点击圆的头像&#xff08;.person-msg&#xff09;弹出白色底框(.person-centre)。点击圆头像以外的区域隐藏白色底框 html代码 <div class"per_c"><div class"person-msg pull-right"><i…

如何在Ubuntu上轻松安装Oracle Java

Ubuntu上的开发人员习惯于至少看到两种Java风格。 OpenJDK是Java运行时和编译器的开源构建。 Oracle JDK以此为基础&#xff0c;但是增加了一些封闭源组件。 从理论上讲&#xff0c;OpenJDK是Java 7的官方参考实现 &#xff0c;并且完全可以满足您的所有需求。 在实践中&#…

今天发现新大陆:haml和Emmet

其实一开始小渣渣我只是想接触一下&#xff08;css预处理器&#xff09;sass&#xff0c;可是突然冒出一个haml。 原文是酱紫的。 Sass 是采用 Ruby 语言编写的一款 CSS 预处理语言&#xff0c;它诞生于2007年&#xff0c;是最大的成熟的 CSS 预处理语言。最初它是为了配合 H…

Docker系列(五):.Net Core实现k8s健康探测机制

k8s通过liveness来探测微服务的存活性&#xff0c;判断什么时候该重启容器实现自愈。比如访问 Web 服务器时显示 500 内部错误&#xff0c;可能是系统超载&#xff0c;也可能是资源死锁&#xff0c;此时 httpd 进程并没有异常退出&#xff0c;在这种情况下重启容器可能是最直接…

编写java程序计算梯形面积_学习练习 java面向对象梯形面积

package com.hanqi;public class Ladder {double ShangDi;double XiaDi;double Gao;double MianJi;Ladder(double ShangDi, double XiaDi, double Gao){//使用参数来初始化属性//this 代表当前类this.ShangDi ShangDi;this.XiaDi XiaDi;this.Gao Gao;}//方法的命名&#xff…

02-再探MySQL数据库

一、数据类型 1、数值类型 a、整数类型 整数类型&#xff1a;TINYINT SMALLINT MEDIUMINT INT BIGINT 作用&#xff1a;存储年龄&#xff0c;等级&#xff0c;id&#xff0c;各种号码等。 tinyint[(m)] [unsigned] [zerofill]小整数&#xff0c;数据类型用于保存一些范围的整数…

js原生带缩略图的图片切换效果

js原生带缩略图的图片切换效果 本例中用到的 moveElement(elementID,final_x,final_y,interval)是来自《JavaScript DOM编程艺术&#xff08;中文第二版&#xff09;》一书第10章中有一段代码。&#xff08;可以直接baidu&#xff09; 左边是banner图&#xff0c;右边是缩略图…