题目大意

有一个串\(s\),一开始只知道它的一个前缀。有\(q\)(\(q\leq 10^4\))个操作,操作有两种:1.给一个字符串,表示\(s\)(\(s\)总长\(\leq 6\times 10^5\))当前未知部分的前缀;2.给一个字符串,问\(s\)的已知部分中有几个子串和该串相同,询问串总长\(\leq 3\times 10^6\)。强制在线。

题解

后缀自动机一边extend一边用LCT维护right集合大小。

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define LL long long
#define maxn 600007
#define maxm 1200007
#define maxk 3000007
#define ls son[u][0]
#define rs son[u][1]
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
namespace LCT
{
int son[maxm][2],fa[maxm],mk[maxm],num[maxm],stk[maxm],tp;
void mark(int u,int k){if(u)mk[u]+=k,num[u]+=k;}
void pd(int u){if(u&&mk[u])mark(ls,mk[u]),mark(rs,mk[u]),mk[u]=0;}
int nort(int u){return son[fa[u]][0]==u||son[fa[u]][1]==u;}
int getso(int u){return son[fa[u]][0]!=u;}
void rot(int u)
{
int fu=fa[u],ffu=fa[fu],l=getso(u),fl=getso(fu),r=l^1,rson=son[u][r];
son[u][r]=fu,son[fu][l]=rson;if(nort(fu))son[ffu][fl]=u;if(rson)fa[rson]=fu;fa[u]=ffu,fa[fu]=u;
}
void splay(int u)
{
int v=u;stk[tp=1]=v;while(nort(v))stk[++tp]=v=fa[v];
while(tp)pd(stk[tp--]);
while(nort(u)){int fu=fa[u];if(nort(fu))rot(getso(u)^getso(fu)?u:fu);rot(u);}
}
void acs(int u){for(int v=0;u;v=u,u=fa[u])splay(u),rs=v;}
void cut(int u){acs(u),splay(u),fa[ls]=0,ls=0;}//fth[u]=v
void link(int u,int v){fa[u]=v;}
void opt(int u,int k){acs(u),splay(u),mark(u,k);}
void add(int u,int v){num[u]=num[v];}
int ask(int u){splay(u);return num[u];}
}
int mask,n,len,ch[maxm][26],dis[maxm],r[maxm],fa[maxm],lst,cntnd,rt,ans;
char s[maxk],t[6];
int gx(char c){return c-'A';}
void ext(char c)
{
int p=lst,np=++cntnd,v=gx(c);dis[np]=dis[p]+1,lst=np;
for(;p&&!ch[p][v];p=fa[p])ch[p][v]=np;
if(!p)fa[np]=rt,LCT::link(np,rt);
else
{
int q=ch[p][v];
if(dis[q]==dis[p]+1)fa[np]=q,LCT::link(np,q);
else
{
int nq=++cntnd;dis[nq]=dis[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
LCT::cut(q),LCT::add(nq,q),LCT::link(nq,fa[q]),LCT::link(q,nq),LCT::link(np,nq);
fa[nq]=fa[q],fa[np]=fa[q]=nq;
for(;p&&ch[p][v]==q;p=fa[p])ch[p][v]=nq;
}
}
LCT::opt(np,1);
}
int main()
{
rt=lst=++cntnd;
scanf("%d%s",&n,s);len=strlen(s);
rep(i,0,len-1)ext(s[i]);
while(n--)
{
scanf("%s%s",t,s),len=strlen(s);int msk=mask;
rep(i,0,len-1)
{
msk=(msk*131+i)%len;
swap(s[i],s[msk]);
}
if(t[0]=='Q')
{
int now=rt;
rep(i,0,len-1)
{
int v=gx(s[i]);
now=ch[now][v];
if(!now)break;
}
if(!now)ans=0;
else {ans=LCT::ask(now);}
write(ans);
mask^=ans;
}
else{rep(i,0,len-1)ext(s[i]);}
}
return 0;
}
一些感想

既弱智又星际怎么办,在线等,挺急的!

并不对劲的复健训练-p5212 SubString的更多相关文章

  1. 并不对劲的复健训练-CF1187D

    题目大意 有两个长度为\(n\)的序列\(a_1,...,a_n\),\(b_1,...,b_n\)(\(a,b\leq n\leq 3\times 10^5\) ).一次操作是选取 \([l,r]\ ...

  2. 并不对劲的复健训练-bzoj5250:loj2473:p4365:[九省联考2018]秘密袭击

    题目大意 有一棵\(n\)(\(n\leq 1666\))个点的树,有点权\(d_i\),点权最大值为\(w\)(\(w\leq 1666\)).给出\(k\)(\(k\leq n\)),定义一个选择 ...

  3. 并不对劲的复健训练-bzoj5339:loj2578:p4593:[TJOI2018]教科书般的亵渎

    题目大意 题目链接 题解 先将\(a\)排序. \(k\)看上去等于怪的血量连续段的个数,但是要注意当存在\(a_i+1=a_{i+1}\)时,虽然它们之间的连续段为空,但是还要算上:而当\(a_m= ...

  4. 并不对劲的复健训练-CF1205B Shortest Cycle

    题目大意 有\(n\)(\(n\leq 10^5\))个数\(a_1,...,a_n\)(\(a\leq 10^{18}\)).有一个图用这个方法生成:若\(a_i\)按位与\(a_j\)不为0,则在 ...

  5. 并不对劲的复健训练-bzoj5249:loj2472:p4364[2018多省联考]IIIDX

    题目大意 给出\(n,k,d_1,...,d_n\)(\(n\leq 5\times 10^5,1<k\leq 10^9,d\leq 10^9,k\in R\)).有一个满足 对于每个点\(i\ ...

  6. 并不对劲的复健训练-bzoj5253:loj2479:p4384:[2018多省联考]制胡窜

    题目大意 给出一个字符串\(S\),长度为\(n\)(\(n\leq 10^5\)),\(S[l:r]\)表示\(S_l,S_{l+1}...,S_r\)这个子串.有\(m\)(\(m\leq 3\t ...

  7. 并不对劲的复健训练-bzoj5301:loj2534:p4462 [CQOI2018]异或序列

    题目大意 给出一个序列\(a_1,...,a_n\)(\(a,n\leq 10^5\)),一个数\(k\)(\(k\leq 10^5\)),\(m\)(\(m\leq10^5\))次询问,每次询问给\ ...

  8. 并不对劲的复健训练-p3674

    题目大意 给出序列$ a_1,...,a_n $ ( $ n\leq10^5,a\leq 10^5 $ ),有\(m\) ( \(m\leq 10^5\))个以下三类询问: (1)给出\(l,r,k\ ...

  9. 2019NOIP算法复健+学习

    前言: 原本因为kma太弱,很多算法没学学了也不会用,打算设置密码给自己看.后来想了想,觉得也没有必要,既然决定了要学些东西到脑子里,就没什么好丢人的. 注:"×"意为完全没学,& ...

随机推荐

  1. 【APUE】第3章 文件I/O (3) 文件共享、原子操作、函数dup/dup2、函数sync/fsync/fdatasync、函数fcntl、函数ioct1、目录/dev/fd 使用说明

    1.文件共享 UNIX系统支持在不同的进程间共享打开文件.为了说明这种共享,以下介绍内核用于所有I/O的数据结构. 内核使用3种数据结构表示打开文件,它们之间的关系决定了在文件共享方面一个进程对另一个 ...

  2. SpringMVC 请求映射注解

    @GetMapping: 处理get请求,传统的RequestMapping来编写应该是@RequestMapping(value = “/get/{id}”, method = RequestMet ...

  3. Leetcode题目46.全排列(回溯+深度优先遍历+状态重置-中等)

    题目描述: 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], ...

  4. mysql:启动服务时遇到的问题

    1.cmd命令: 在切换路径时,如果要切到另外一个磁盘,比如从C盘切到E盘,命令如下: cd /d 你要切换的路径 2.错误:“服务名无效” 问题原因:mysql服务没有安装.(参考:https:// ...

  5. Hbuilder用自有证书打包 ios App上架AppStore流程

    最近在用Hbuilder做跨平台开发,经过一番研究终于在苹果商店上架成功了一款产品!这款产品就很简单,直接用hbuilder打包好,然后上传到商店即可.这里参照ios app提交应用商店 这篇文章结合 ...

  6. RDS数据库全量恢复方案

    一.全量恢复 恢复最近的快照,将快找之前的数据全量恢复 二.增量恢复 下载对应的binlog日志导入到数据库 三.还没有备份的binlog日志获取方法 首先连接 RDS for MySQL 后查看当前 ...

  7. shiro中接入单点登录功能

    最近新建的系统中使用了shiro,而shiro框架中包含登录认证和鉴权的功能,因为我们系统要统一接入公司内部的单点登录(isso)系统,所以通过isso的登录用户,需要在shiro中置为已认证,一下提 ...

  8. Linux vi/vim命令

    转自:http://www.runoob.com/linux/linux-vim.html Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一 ...

  9. Python实现的寻找前5个默尼森数算法示例

    Python实现的寻找前5个默尼森数算法示例 本文实例讲述了Python实现的寻找前5个默尼森数算法.分享给大家供大家参考,具体如下: 找前5个默尼森数. 若P是素数且M也是素数,并且满足等式M=2* ...

  10. sysctl 命令

    sysctl命令 被用于在内核运行时动态地修改内核的运行参数,可用的内核参数在目录/proc/sys中.它包含一些TCP/ip堆栈和虚拟内存系统的高级选项, 这可以让有经验的管理员提高引人注目的系统性 ...