题意

给定两个字符串 A 和 B,求下面四个问题的答案:

1.在 A 的子串中,不是 B 的子串的字符串的数量。

2.在 A 的子串中,不是 B 的子序列的字符串的数量。

3.在 A 的子序列中,不是 B 的子串的字符串的数量。

4.在 A 的子序列中,不是 B 的子序列的字符串的数量。

其中子串是指本质不同的子串,不同的位置相同的串也只算一个串

|S|<=2000

分析

构造俩自动机然后同时跑

题解

构造一个子序列自动机,再构造一个后缀自动机,然后从根依次转移,记录状态上的信息,记忆化一下。

#include <bits/stdc++.h>
using namespace std;
const int mo=1e9+7, Lim=100005;
int nid;
struct node {
node *c[26], *f;
int len, s, id;
bool flag;
void init() {
memset(c, 0, sizeof c);
f=0;
len=s=0;
flag=0;
}
}Po[Lim], *iT=Po, *root[2], *last[2], *rt[2];
node *newnode() {
iT->init();
return iT++;
}
void init() {
root[0]=newnode();
root[1]=newnode();
last[0]=root[0];
last[1]=root[1];
rt[0]=newnode();
rt[1]=newnode();
}
void add1(int who, int ch) {
node *now=last[who], *x=newnode();
last[who]=x;
x->len=now->len+1;
x->id=nid++;
for(; now && !now->c[ch]; now=now->f) {
now->c[ch]=x;
}
if(!now) {
x->f=root[who];
return;
}
node *y=now->c[ch];
if(y->len==now->len+1) {
x->f=y;
return;
}
node *z=newnode();
*z=*y;
z->id=nid++;
z->len=now->len+1;
x->f=y->f=z;
for(; now && now->c[ch]==y; now=now->f) {
now->c[ch]=z;
}
}
void cal(node *x) {
if(x->flag) {
return;
}
x->flag=1;
x->s=1;
for(int ch=0; ch<26; ++ch) {
if(x->c[ch]) {
cal(x->c[ch]);
x->s+=x->c[ch]->s;
if(x->s>=mo) {
x->s-=mo;
}
}
}
}
void build1(int who, char *s) {
nid=1;
for(; *s; ++s) {
add1(who, *s-'a');
}
cal(root[who]);
}
void build2(int who, char *s) {
nid=1;
static node *tc[26];
memset(tc, 0, sizeof tc);
for(; *s; --s) {
node *now=newnode();
now->id=nid++;
for(int ch=0; ch<26; ++ch) {
now->c[ch]=tc[ch];
}
tc[*s-'a']=now;
}
for(int ch=0; ch<26; ++ch) {
rt[who]->c[ch]=tc[ch];
}
cal(rt[who]);
}
int vis[5005][5005];
int getans(node *x, node *y) {
if(!x) {
return 0;
}
if(!y) {
return x->s;
}
if(vis[x->id][y->id]!=-1) {
return vis[x->id][y->id];
}
int ret=0;
for(int ch=0; ch<26; ++ch) {
ret+=getans(x->c[ch], y->c[ch]);
if(ret>=mo) {
ret-=mo;
}
}
return vis[x->id][y->id]=ret;
}
char s[2][2005], *it[2];
int main() {
init();
scanf("%s%s", s[0], s[1]);
build1(0, s[0]);
build1(1, s[1]);
for(int i=0; i<2; ++i) {
for(it[i]=s[i]; *(it[i]+1); ++it[i]);
}
build2(0, it[0]);
build2(1, it[1]);
memset(vis, -1, sizeof vis); printf("%d\n", getans(root[0], root[1]));
memset(vis, -1, sizeof vis); printf("%d\n", getans(root[0], rt[1]));
memset(vis, -1, sizeof vis); printf("%d\n", getans(rt[0], root[1]));
memset(vis, -1, sizeof vis); printf("%d\n", getans(rt[0], rt[1]));
return 0;
}

弱省互测#0 t2的更多相关文章

  1. 弱省互测#2 t2

    题意 给两个树,大小分别为n和m,现在两棵树各选一些点(包括1),使得这棵树以1号点为根同构(同构就是每个点的孩子数目相同),求最大的同构树.(n, m<=500) 分析 我们从两棵树中各取出一 ...

  2. 弱省互测#0 t3

    Case 1 题意 要求给出下面代码的答案然后构造输入. 给一个图, n 个点 m 条边 q 次询问,输出所有点对之间最大权值最小的路径. 题解 把每一个询问的输出看成一条边,建一棵最小生成树. Ca ...

  3. 弱省互测#0 t1

    题意 给一个\(N \times M\)的01网格,1不能走,从起点\((1, 1)\)走到\((N, M)\),每次只能向下或向右走一格,问两条不相交的路径的方案数.(n, m<=1000) ...

  4. 【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)

    Description 给定一颗 \(n\) 个点的树,带边权. 你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...

  5. 弱省互测#2 t3

    题意 给出\(n\)个01字节和\(m\)个01字节,要求用后者去匹配前者,两个串能匹配当且仅当除了每个字节末位不同,其他位都要相同.问匹配后者至少有多少个末位不同.(\(1 \le m \le n ...

  6. 弱省互测#1 t3

    题意 给出一棵n个点的树,求包含1号点的第k小的连通块权值和.(\(n<=10^5\)) 分析 k小一般考虑堆... 题解 堆中关键字为\(s(x)+min(a)\),其中\(s(x)\)表示\ ...

  7. 【2018集训队互测】【XSY3372】取石子

    题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...

  8. 【loj2461】【2018集训队互测Day 1】完美的队列

    #2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...

  9. 洛谷 P4463 - [集训队互测 2012] calc(多项式)

    题面传送门 & 加强版题面传送门 竟然能独立做出 jxd 互测的题(及其加强版),震撼震撼(((故写题解以祭之 首先由于 \(a_1,a_2,\cdots,a_n\) 互不相同,故可以考虑求出 ...

随机推荐

  1. [BZOJ1552][Cerc2007]robotic sort

    [BZOJ1552][Cerc2007]robotic sort 试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数 ...

  2. iOS 用户的隐私数据-privacy-sensitive data

    1  Xcode 报错:This app has crashed because it attempted to access privacy-sensitive data without a usa ...

  3. 6 VC维

    1 VC维的定义 VC维其实就是第一个break point的之前的样本容量.标准定义是:对一个假设空间,如果存在N个样本能够被假设空间中的h按所有可能的2的N次方种形式分开,则称该假设空间能够把N个 ...

  4. [转]大数据时代,python竟是最好的语言?

      随着大数据疯狂的浪潮,新生代的工具Python得到了前所未有的爆发.简洁.开源是这款工具吸引了众多粉丝的原因.目前Python最热的领域,非数据分析和挖掘莫属了.从以Pandas为代表的数据分析领 ...

  5. Java字节流和字符流区别

    1.字节流:直接操作文件本身. 2.字符流:通过缓冲区来操作文件. 所有的文件在硬盘或在传输时都是以字节的方式进行的,包括图片等都是按字节的方式存储的,而字符是只有在内存中才会形成,所以在开发中,字节 ...

  6. Ubuntu16.04安装有道词典

    1.首先需要安装依赖包gstreamer0.10-plugins-ugly_0.10.19-2.1_amd64.deb,但是该依赖包 仍有两个依赖包需要提前安装,这三个依赖包都可以从这里下载 下载之后 ...

  7. androidstdio偶遇一

    android的错误 今天在安装androidstdio的过程中产生了遇到了一个错误(之前一直没有重新安装,因为觉得麻烦,但是电脑慢成狗了,只好重新安装....)那么现在步入正题.     首先安装的 ...

  8. iOS开发者联系 联系方式

    苹果开发者客服电话地址:https://developer.apple.com/contact/phone.php 中国大陆地区客服电话: 中国香港地区客服电话:() 中国台湾地区客服电话: 链接地址 ...

  9. 使用VBScript实现设置系统环境变量的小程序

    本人有点桌面洁癖,桌面上只放很少的东西,很多软件都用快捷键调出.最近频繁用到一个软件,我又不想放个快捷方式在桌面,也不想附到开始菜单,于是乎想将其所在目录附加到系统环境变量Path上,以后直接在运行中 ...

  10. 【Java EE 学习 57】【酒店会员管理系统之分页模板书写】

    分页一直是一个比较麻烦的问题,特别是在我做的这个系统中更是有大量的分页,为了应对该问题,特地写了一个模板以方便代码重用,该模板包括后台分页的模板.前端显示的模板两部分. 一.分页分析 分页需要三种类型 ...