test20181020 B君的第二题
B君的第二题
分析
题目就是让你求文本框与s匹配到了哪个位置。
考场70分
一看就是裸的kmp,直接打上去。
const int MAXN=1e5+8;
char s[MAXN],t[MAXN];
int n,m;
int nx[MAXN];
int f[MAXN],len;
int main()
{
freopen("xining.in","r",stdin);
freopen("xining.out","w",stdout);
scanf("%s",s+1);
n=strlen(s+1);
scanf("%s",t+1);
m=strlen(t+1);
for(int i=2;i<=n;++i)
{
int p=nx[i-1];
while(p&&s[p+1]!=s[i])
p=nx[p];
if(s[p+1]==s[i])
++p;
nx[i]=p;
}
printf("%d\n",n);
for(int i=1;i<=m;++i)
{
if(t[i]=='-')
{
--len;
if(len<0)
len=0;
printf("%d\n",n-f[len]);
continue;
}
// cerr<<"pro "<<i<<endl;
int p=f[len];
// cerr<<" p="<<p<<endl;
while(p&&s[p+1]!=t[i])
p=nx[p];
if(s[p+1]==t[i])
++p;
f[++len]=p;
// cerr<<" p="<<p<<endl;
printf("%d\n",n-p);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
结果TLE了。实际上时间复杂度\(O(n^2)\)
标解
这道题能卡kmp,是因为往回走后重新匹配跳next时复杂度没了保证。
退格操作可以让匹配长度剧增,这与kmp要满足长度增加量最多为文本串的长度的性质不符,所以要被卡。
B君:可以前n/2都是a,然后后面一个-一个b交替出现,就可以把kmp卡成n方的了。
但是AC自动机中的一个构建优化是把不存在的儿子补齐,所以考虑AC自动机。
然后因为AC自动机是在Trie图上建的,距离不能直接求,所以要预处理。
时间复杂度\(O(n)\)
const int MAXN=1e5+7;
vector<int>a[MAXN];
int d[MAXN];
const int CHARSET=26;
struct Trie
{
int sz;
int to[MAXN][CHARSET];
int nx[MAXN];
int fa[MAXN];
int v[MAXN];
il void ins(rg char*s)
{
rg int p=0;
for(;*s;++s)
{
rg int c=*s-'a';
if(to[p][c]==0)
{
to[p][c]=++sz;
fa[sz]=p;
}
p=to[p][c];
}
v[p]=1;
}
il void build()
{
rg queue<int>Q;
Q.push(0);
while(!Q.empty())
{
rg int x=Q.front();
Q.pop();
v[x]|=v[nx[x]];
for(rg int i=0;i<CHARSET;++i)
{
if(to[x][i])
{
nx[to[x][i]]=x?to[nx[x]][i]:0;
Q.push(to[x][i]);
}
else
{
to[x][i]=x?to[nx[x]][i]:0;
}
}
}
for(rg int i=0;i<=sz;++i)
for(rg int j=0;j<CHARSET;++j)
{
a[to[i][j]].push_back(i);
}
memset(d,0x3f,sizeof d);
for(rg int i=0;i<=sz;++i)
if(v[i])
{
Q.push(i);
d[i]=0;
}
while(!Q.empty())
{
rg int x=Q.front();
Q.pop();
for(rg int i=0;i<a[x].size();++i)
{
rg int y=a[x][i];
if(d[y]>d[x]+1)
{
d[y]=d[x]+1;
Q.push(y);
}
}
}
}
}T;
char s[MAXN],t[MAXN];
int f[MAXN],len;
int main()
{
freopen("xining.in","r",stdin);
freopen("xining.out","w",stdout);
scanf("%s",s);
T.ins(s);
T.build();
scanf("%s",t);
printf("%d\n",d[f[len]]);
for(rg int i=0;t[i];++i)
{
if(t[i]=='-')
{
if(len>0)
--len;
}
else
{
rg int x=T.to[f[len]][t[i]-'a']; // edit 1
f[++len]=x;
}
// cerr<<"f="<<f[len]<<endl;
printf("%d\n",d[f[len]]);
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
test20181020 B君的第二题的更多相关文章
- B 君的第二题 (hongkong)
B 君的第二题 (hongkong) 题目大意: 一个长度为\(n(n\le2\times10^5)\)的数组,给定一个数\(k(k\le40)\).用\(a[i][j]\)表示该数组\(i\)次前缀 ...
- test20181016 B君的第二题
题意 分析 考场暴力50分. 考虑bfs序,一个点的儿子节点的bfs序一定连续,所以对bfs序建线段树,努力打一下就行了. 时间复杂度\(O(n \log n + m \log n)\) #inclu ...
- test20181017 B君的第二题
题意 分析 考场50分 旁边的L君告诉我,求的就是非升子序列的个数,于是写了个树状数组. 但是\(\mod{2333} > 0\)还需要组合数中没有2333的倍数,所以实际上只得了\(a_i \ ...
- test20181015 B君的第二题
题意 分析 考场85分 用multiset暴力,由于教练的机子飞快,有写priority_queue水过了的人. #include<cstdlib> #include<cstdio& ...
- test20181020 B君的第一题
题意 分析 二次剩余问题. x,y相当于二次方程 \[ x^2-bx+c=0 \mod{p} \] 的两根. 摸意义下的二次方程仍然考虑判别式\(\Delta=b^2-4c\). 它能开根的条件是\( ...
- test20181019 B君的第二题
题意 分析 快速子集和变换以及快速超集和变换的裸题. 用\(f(s)\)表示集合s的方案数,初始化为输入中s出现的次数. 做一遍快速子集和变换,此时f(s)表示s及其子集在输入中出现的次数. 对所有f ...
- Java蓝桥杯02——第二题集锦:生日蜡烛、星期一、方格计数、猴子分香蕉
第二题 生日蜡烛(结果填空) 某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛. 现在算起来,他一共吹熄了236根蜡烛. 请问,他从多少岁开始过生日party的? 请填 ...
- 05:统计单词数【NOIP2011复赛普及组第二题】
05:统计单词数 总时间限制: 1000ms 内存限制: 65536kB 描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次 ...
- 常见面试第二题之什么是Context
今天的面试题,也就是我们常见面试题系列的第二题,我们来讲一讲android中的context.我相信大家android开发者一定对于这个context非常熟悉,肯定都有使用过,肯定没有没使用过的.但是 ...
随机推荐
- RabittMQ实践(二): RabbitMQ 与spring、springmvc框架集成
一.RabbitMQ简介 1.1.rabbitMQ的优点(适用范围)1. 基于erlang语言开发具有高可用高并发的优点,适合集群服务器.2. 健壮.稳定.易用.跨平台.支持多种语言.文档齐全.3. ...
- VS2010/MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
前面几节鸡啄米为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为“计算”按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但是还有个遗留的 ...
- BUCT20180814邀请赛 Solution
A:SUM 水. #include<bits/stdc++.h> using namespace std; #define N 100010 typedef long long ll; i ...
- 高级Bash脚本编程(二)
高级Bash脚本编程(二) 退出 退出状态码 退出:exit 被用来结束一个脚本,它也返回一个值,并且这个值会传递给脚本的父进程,父进程会使用这个值做下一步的处理. 每个命令都会返回一个退出状态码,成 ...
- (转载)ubuntu卸载opencv并重装opencv3.0.0
ubuntu卸载opencv并重装opencv3.0.0 一. 卸载opencv2.4.9: Going to the "build" folder directory of op ...
- Gym - 100283F Bakkar In The Army(二分)
https://vjudge.net/problem/Gym-100283F 题意: 1 1 2 1 1 2 3 2 1 1 2 3 4 3 2 1 .... 给出这样的序列,然后给出一个n,计算从1 ...
- Java中的组合与聚合
组合和聚合是有很大区别的,这个区别不是在形式上,而是在本质上:比如A类中包含B类的一个引用b,当A类的一个对象消亡时,b这个引用所指向的对象也同时消亡(没有任何一个引用指向它,成了垃圾对象),这种情况 ...
- 【Python】模块学习之matplotlib柱状图、饼状图、动态图及解决中文显示问题
前言 众所周知,通过数据绘图,我们可以将枯燥的数字转换成容易被人们接受的图表,从而让人留下更加深刻的印象.而大多数编程语言都有自己的绘图工具,matplotlib就是基于Python的绘图工具包,使用 ...
- Tensorflow一些常用基本概念与函数(一)
1.tensorflow的基本运作 为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始: import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf. ...
- <<网络是怎样连接的>>笔记第2章用电信号传输Tcp/ip数据
创建套接字: 协议栈的内部结构.套接字的实体,以及创建套接字的操作过程 连接服务器: “连接”具体是进行怎样的操作,在这个过程中协议栈到底是如何工作的, 以及客户端和服务器是如何进行交互的. 收发数据 ...