BZOJ5408: string(广义后缀自动机,LCT)
解题思路:
首先在后缀树上,确定了一个节点就相当于确定了一个串,那么一个点对应的串在另外一个点对应的串产生贡献,当且仅当这个点在当前点子树内。
那么考虑一个新的点在串中对串答案的贡献在一条树链上或者反过来说,就是产生贡献的点在这个点子树内。
才知道自己写的广义后缀自动机板子是错的QAQ
考虑n非常小,贡献可以单独算,再配合BZOJ2555的启发,这道题就可以使用LCT轻松地解决了。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll tr[spc].ch[0]
#define rrr tr[spc].ch[1]
#define ls ch[0]
#define rs ch[1]
typedef long long lnt;
struct trnt{
int ch[];
int fa;
int val[];
int lzt[];
bool anc;
}tr[];
struct sant{
int tranc[];
int pre;
int len;
}s[];
int n,m;
lnt sum;
int siz;
int type;
int lastans;
int pos[][];
char str[];
bool whc(int spc)
{
return tr[tr[spc].fa].rs==spc;
}
void add(int spc,int no,int v)
{
if(!spc)return ;
tr[spc].val[no]+=v;
tr[spc].lzt[no]+=v;
return ;
}
void pushdown(int spc)
{
for(int i=;i<=n;i++)
{
if(tr[spc].lzt[i])
{
add(lll,i,tr[spc].lzt[i]);
add(rrr,i,tr[spc].lzt[i]);
tr[spc].lzt[i]=;
}
}
}
void recal(int spc)
{
if(!tr[spc].anc)recal(tr[spc].fa);
pushdown(spc);
return ;
}
void rotate(int spc)
{
int f=tr[spc].fa;
bool k=whc(spc);
tr[f].ch[k]=tr[spc].ch[!k];
tr[spc].ch[!k]=f;
if(tr[f].anc)
{
tr[f].anc=false;
tr[spc].anc=true;
}else tr[tr[f].fa].ch[whc(f)]=spc;
tr[spc].fa=tr[f].fa;
tr[f].fa=spc;
tr[tr[f].ch[k]].fa=f;
return ;
}
void splay(int spc)
{
recal(spc);
while(!tr[spc].anc)
{
int f=tr[spc].fa;
if(tr[f].anc)
{
rotate(spc);
return ;
}
if(whc(spc)^whc(f))rotate(spc);
else rotate(f);
rotate(spc);
}
return ;
}
void access(int spc)
{
int lst=;
while(spc)
{
splay(spc);
tr[rrr].anc=true;
tr[lst].anc=false;
rrr=lst;
lst=spc;
spc=tr[spc].fa;
}
return ;
}
void ADD(int from,int to,int cmd)
{
recal(from);
for(int i=;i<=n;i++)
{
if(tr[from].val[i])
{
add(to,i,tr[from].val[i]*cmd);
}
}
return ;
}
void link(int x,int f)
{
access(f);
splay(f);
splay(x);
ADD(x,f,);
tr[x].fa=f;
return ;
}
void cut(int spc)
{
access(spc);
splay(spc);
int spc_=lll;
lll=tr[spc_].fa=;
tr[spc_].anc=true;
splay(spc_);
ADD(spc,spc_,-);
return ;
}
int decode(int c)
{
if(type)return (c xor lastans)%;
return c;
}
int Insert(int fin,int no,int c)
{
if(s[fin].tranc[c]&&s[s[fin].tranc[c]].len==s[fin].len+)
{
int spc=s[fin].tranc[c];
access(spc);
splay(spc);
add(spc,no,);
return spc;
}
int nwp,lsp,nwq,lsq,flag=;
nwp=++siz;tr[nwp].val[no]=;
s[nwp].len=s[fin].len+;
for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)s[lsp].tranc[c]=nwp;
if(!lsp)
{
s[nwp].pre=;
link(nwp,);
}else{
lsq=s[lsp].tranc[c];
if(s[lsq].len==s[lsp].len+)
{
s[nwp].pre=lsq;
link(nwp,lsq);
}else{
if(s[nwp].len==s[lsp].len+)flag=;
nwq=++siz;
s[nwq]=s[lsq];
s[nwq].len=s[lsp].len+;
s[nwp].pre=s[lsq].pre=nwq;
cut(lsq);
link(nwq,s[nwq].pre);
link(nwp,nwq);
link(lsq,nwq);
while(s[lsp].tranc[c]==lsq)
{
s[lsp].tranc[c]=nwq;
lsp=s[lsp].pre;
}
}
}
sum+=s[nwp].len-s[s[nwp].pre].len;
if(flag)return nwq;
return nwp;
}
void init(void)
{
for(int i=;i<=;i++)tr[i].anc=true;
siz=;
return ;
}
int query(char *a)
{
int len=strlen(a+);
int spc=;
for(int i=;i<=len;i++)
{
int c=a[i]-'';
spc=s[spc].tranc[c];
if(!spc)return ;
}
int ans=-;
recal(spc);
for(int i=;i<=n;i++)
ans=std::max(ans,tr[spc].val[i]);
return ans;
}
int main()
{
scanf("%d%d",&n,&type);
init();
for(int i=;i<=n;i++)
{
scanf("%s",str+);
int len=strlen(str+);
pos[i][]=;
for(int j=;j<=len;j++)
pos[i][]=Insert(pos[i][],i,str[j]-'');
}
scanf("%d",&m);
for(int r=;r<=m;r++)
{
for(int i=;i<=n;i++)pos[i][r]=pos[i][r-];
int opt;
scanf("%d",&opt);
if(opt==)
{
int x,y;
scanf("%d%d",&x,&y);
y=decode(y);
pos[x][r]=Insert(pos[x][r],x,y);
}
if(opt==)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
int spc=pos[x][y];
recal(spc);
lastans=tr[spc].val[z];
printf("%d\n",lastans);
}
if(opt==)printf("%lld\n",sum);
if(opt==)
{
scanf("%s",str+);
lastans=query(str);
printf("%d\n",lastans);
}
}
return ;
}
BZOJ5408: string(广义后缀自动机,LCT)的更多相关文章
- 2020牛客暑期多校训练营(第四场) C - Count New String (字符串,广义后缀自动机,序列自动机)
Count New String 题意: 定义字符串函数 \(f(S,x,y)(1\le x\le y\le n)\),返回一个长度为y-x+1的字符串,第 i 位是 \(max_{i=x...x+k ...
- BZOJ 3277 串 (广义后缀自动机)
3277: 串 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 309 Solved: 118 [Submit][Status][Discuss] De ...
- BZOJ 3473: 字符串 [广义后缀自动机]
3473: 字符串 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 354 Solved: 160[Submit][Status][Discuss] ...
- cf666E. Forensic Examination(广义后缀自动机 线段树合并)
题意 题目链接 Sol 神仙题Orz 后缀自动机 + 线段树合并 首先对所有的\(t_i\)建个广义后缀自动机,这样可以得到所有子串信息. 考虑把询问离线,然后把\(S\)拿到自动机上跑,同时维护一下 ...
- SP8093 JZPGYZ - Sevenk Love Oimaster(广义后缀自动机)
题意 题目链接 Sol 广义后缀自动机板子题..和BZOJ串那个题很像 首先建出询问串的SAM,然后统计一下每个节点被多少个串包含 最后直接拿询问串上去跑就行了 #include<bits/st ...
- BZOJ 3473: 字符串 (广义后缀自动机)
/* 广义后缀自动机, 每次加入维护 该right集合的set, 然后可以更新所有的parent,最终能够出现在k个串中right集合也就是set大小大于等于k的部分 这样的话就给了我们要跳的节点加了 ...
- bzoj 3277 串 && bzoj 3473 字符串 && bzoj 2780 [Spoj]8093 Sevenk Love Oimaster——广义后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3277 https://www.lydsy.com/JudgeOnline/problem.p ...
- 【BZOJ2780】Sevenk Love Oimaster【广义后缀自动机】
题意 给出你n个字符串和q个查询,每个查询给出一个字符串s,对于每个查询你都要输出这个字符串s在上面多少个字符串中出现过. 分析 广义后缀自动机的裸题.建好SAM以后再跑一遍得到每个状态的ocu和la ...
- 【BZOJ3227】串【广义后缀自动机】
题意 给出n个字符串,问每个字符串中有多少子串是这所有的n个字符串中至少k个的子串. 分析 广义后缀自动机模板题.对这n个串建广义后缀自动机,对于每个状态维护两个值cou[u]和lcu[u]分别代表拥 ...
随机推荐
- Qt之QStackedLayout
简述 QStackedLayout继承自QLayout. QStackedLayout类提供了多页面切换的布局,一次只能看到一个界面. QStackedLayout可用于创建类似于QTabWidget ...
- bzoj1005: [HNOI2008]明明的烦恼(prufer+高精度)
1005: [HNOI2008]明明的烦恼 题目:传送门 题解: 毒瘤题啊天~ 其实思考的过程还是比较简单的... 首先当然还是要了解好prufer序列的基本性质啦 那么和1211大体一致,主要还是利 ...
- windows 快捷调用
win + x:系统常用管理工具: win + r,或者按下 windows 键,在输入框中输入: services.msc:服务管理: diskmgmt.msc:磁盘管理: devmgmt.msc: ...
- Pycharm-连接服务器
- 1.CMD命令
CMD命令:开始->运行->键入cmd或command(在命令行里可以看到系统版本.文件系统版本)1. appwiz.cpl:程序和功能 2. calc:启动计算器 3. certmgr. ...
- 安装Debugging Tools时出现错误Setup could not find the file WinSDK_amd64的处理
安装Debugging Tools时出现错误Setup could not find the file WinSDK_amd64的处理 1.软件来源: 微软官网下载SDK ISO安装包(含有debu ...
- [国家集训队]拉拉队排练 Manancher_前缀和_快速幂
Code: #include <cstdio> #include <algorithm> #include <cstring> using namespace st ...
- pc端如何引用日期插件
页面的html部分 <li> <span>出生日期</span> <input type="text" placeholder=" ...
- [POI2009]KON-Ticket Inspector(二维前缀和+DP)
题意 有n个车站,现在有一辆火车从1到n驶过,给出aij代表从i站上车j站下车的人的个数.列车行驶过程中你有K次检票机会,所有当前在车上的人会被检票,问最多能检多少个不同的人的票 (n<=600 ...
- 对比学习:《深度学习之Pytorch》《PyTorch深度学习实战》+代码
PyTorch是一个基于Python的深度学习平台,该平台简单易用上手快,从计算机视觉.自然语言处理再到强化学习,PyTorch的功能强大,支持PyTorch的工具包有用于自然语言处理的Allen N ...