bzoj2555
2016-06-01 19:34
211 查看
开始时间:19:40
完成时间:21:00
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2555
题目大意:(1):在当前字符串的后面插入一个字符串
(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
题解:最近在写后缀自动机,求一个字符串中出现了几次就相当与其right集合大小,直接上parent树,因为后缀自动机构造特性,可能在parent树改变边,于是用lct维护;
代码:
View Code
完成时间:21:00
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2555
题目大意:(1):在当前字符串的后面插入一个字符串
(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
题解:最近在写后缀自动机,求一个字符串中出现了几次就相当与其right集合大小,直接上parent树,因为后缀自动机构造特性,可能在parent树改变边,于是用lct维护;
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #define maxn 1200005 #define maxl 3000005 using namespace std; int q,n,tot,root,last,mark,m,ri[maxn],lazy[maxn]; char st[maxl]; char ss[20]; struct data{ int fa[maxn],son[maxn][2]; int isroot(int x) {return (son[fa[x]][0]!=x && son[fa[x]][1]!=x);} int which(int x){return son[fa[x]][1]==x;} void change(int x,int k){ ri[x]+=k; lazy[x]+=k;} void pushdown(int x) { if (!lazy[x]) return; if (son[x][1]) change(son[x][1],lazy[x]); if (son[x][0]) change(son[x][0],lazy[x]); lazy[x]=0; } void relax(int x){if (!isroot(x)) relax(fa[x]); pushdown(x);} void turn(int x){ int y=fa[x],wx=which(x),wy=which(y); if (!isroot(y)) son[fa[y]][wy]=x; fa[x]=fa[y]; son[y][wx]=son[x][1-wx]; fa[son[x][1-wx]]=y; son[x][1-wx]=y; fa[y]=x; } void splay(int x) { relax(x); while (!isroot(x)) { if (isroot(fa[x])) turn(x); else if (which(x)==which(fa[x])) turn(fa[x]),turn(x); else turn(x),turn(x); } } void access(int x) { for (int p=0; x; x=fa[x]){ splay(x); son[x][1]=p; p=x;} } void link(int x,int y){ fa[x]=y; access(y); splay(y); change(y,ri[x]); } void cut(int x) { access(x); splay(x); change(son[x][0],-ri[x]); fa[son[x][0]]=0; son[x][0]=0; } }lct; struct date{ int fa[maxn],son[maxn][26],val[maxn]; void prepare(){root=tot=last=1;} int newnode(int x){val[++tot]=x; return tot;} void extend(int x) { int p=last,np=newnode(val[p]+1);ri[np]=1;last=np; for (; p&&!son[p][x]; p=fa[p]) son[p][x]=np; if (!p) fa[np]=root,lct.link(np,root); else { int q=son[p][x]; if (val[q]==val[p]+1){fa[np]=q; lct.link(np,q);} else { int nq=newnode(val[p]+1);ri[nq]=0; memcpy(son[nq],son[q],sizeof(son[q])); fa[nq]=fa[q]; lct.cut(q),lct.link(nq,fa[nq]); fa[q]=fa[np]=nq; lct.link(q,nq),lct.link(np,nq); for (; p && son[p][x]==q; p=fa[p]) son[p][x]=nq; } } } void build() {for (int i=1; i<=m; i++) extend(st[i]-'A');} void query(){ int x,y; bool can=1; x=root; for (int i=1;i<=m;i++){ y=st[i]-'A'; if (!son[x][y]){ can=0; break; }else{ x=son[x][y]; } } if (can==0||x==root) puts("0"); else{ lct.splay(x); printf("%d\n",ri[x]),mark^=ri[x]; } } }SAM; void unzip(){ int temp=mark; for (int i=1;i<=m;i++){ temp=(temp*131+i-1)%m+1; char t=st[i]; st[i]=st[temp],st[temp]=t,temp--; } } int main() { scanf("%d\n",&q);mark=0; scanf("%s",st+1); m=strlen(st+1); SAM.prepare(); SAM.build(); for (int i=1; i<=q; i++) { scanf("%s",ss);scanf("%s",st+1); m=strlen(st+1);unzip(); if (ss[0]=='A') SAM.build(); else SAM.query(); } }
View Code
相关文章推荐
- 2016-06-01错误日志-部署
- 微型抽打气泵FNY较FAY的优势
- 进程互斥
- 微型泵输出流量脉动性研究
- An introduction to the credit scheduler in Xen
- Leetcode 43. Multiply Strings
- 微型气泵最大启动压力试验报告
- js函数(类)的继承机制的设计与实现(四)
- 第十一周项目训练9 存储班长信息的学生类
- JZOJ.3400【GDOI2014模拟】旅行 解题报告
- 微型真空水泵WAJ280降低工作电压测试报告
- Web前端学习第十六天·fighting_JavaScript(DOM编程艺术5-6章)
- READING NOTE: Inside-Outside Net: Detecting Objects in Context with Skip Pooling and Recurrent Neura
- 输入流转为字符串
- 研究微型真空水泵有背压工况下的寿命
- IntelliJ IDEA 2016.1.2开发servlet
- HTTP头Content-Type
- HDU1102(最小生成树Kruskal算法)
- 微型调速气泵KAC050.3样品扼要技术说明
- POJ 3249 Test for Job【SPFA】