博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[NOI2011]阿狸的打字机
阅读量:6707 次
发布时间:2019-06-25

本文共 1309 字,大约阅读时间需要 4 分钟。

[NOI2011]阿狸的打字机

题目大意:

一个老式的打字机按照如下的方式工作:用一个栈存储想要打印的内容(小写英文字母),B键将栈顶字母出栈,P键将栈中所有字母打印出来。

给定长度为\(n(n\le10^5)\)的操作序列(包含\(26\)个小写字母和操作BP)。\(m(m\le10^5)\)次询问,第\(x\)个打印出来的字符串在第\(y\)个打印出来的字符串中出现了几次。

思路:

该打字机的特性使得我们可以很容易地构造出一个AC自动机,插入小写字母同普通的AC自动机,B操作时直接将返回到当前结点在Trie上的父亲即可。

将原问题放到Fail树上,就是\(x\)对应的子树中有多少个结点对应着\(y\)。求出Fail树的DFS序,树状数组维护即可。

源代码:

#include
#include
#include
#include
#include
inline int getint() { register char ch; while(!isdigit(ch=getchar())); register int x=ch^'0'; while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); return x;}const int N=1e5+1,M=1e5;char s[N];int m,par[N],pos[N],in[N],out[N],cnt,ans[M];std::vector
e[N];inline void add_edge(const int &u,const int &v) { e[u].push_back(v); par[v]=u;}struct Query { int x,y,id; bool operator < (const Query &rhs) const { return y
q; for(register int i=0;i<26;i++) { if(ch[0][i]) q.push(ch[0][i]); } while(!q.empty()) { const int &x=q.front(); for(register int i=0;i<26;i++) { int &y=ch[x][i]; if(y) q.push(y); (y?fail[y]:y)=ch[fail[x]][i]; } add_edge(fail[x],x); q.pop(); } } void solve() const { for(register int i=0,j=0,k=0,p=0;s[i];i++) { if(s[i]=='P') { if(++k==q[j].y) { for(;j

转载于:https://www.cnblogs.com/skylee03/p/9445226.html

你可能感兴趣的文章
Adapter
查看>>
TextView支持的HTML标签及其他
查看>>
Windows 安装PyQt5,并整合进Pycharm
查看>>
linux系统安全防护
查看>>
Python之列表和元组
查看>>
像程序员一样地思考
查看>>
为什么你最后哪都没去!!
查看>>
X-FRAME-OPTIONS 防止点击劫持(Clickjacking)的方法
查看>>
软件开发平台有哪些种类联系和区别?
查看>>
单身女人要学会的
查看>>
eclipse中创建maven web项目
查看>>
我的友情链接
查看>>
Ubuntu10.4 桌面空白
查看>>
32位与64位操作系统区别
查看>>
kafka 的原理介绍
查看>>
我的友情链接
查看>>
How to Modify Public Network Information including VIP in Oracle Clusterware
查看>>
内网劫持渗透新姿势:MITMf简要指南
查看>>
动态规划-最长上升子序列(LIS)
查看>>
linux下mysql的root密码忘记解决方法
查看>>