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]分别代表拥 ...
随机推荐
- 使用JMX透过防火墙远程监控tomcat服务
https://my.oschina.net/mye/blog/64879 http://blog.csdn.net/l1028386804/article/details/51547408 http ...
- 如何用一次性密码通过 SSH 安全登录 Linux
有人说,安全不是一个产品,而是一个过程.虽然 SSH 协议被设计成使用加密技术来确保安全,但如果使用不当,别人还是能够破坏你的系统:比如弱密码.密钥泄露.使用过时的 SSH 客户端等,都能引发安全问题 ...
- Android面试题目整理与解说(一)
这一篇文章专门整理一下研究过的Android面试题,内容会随着学习不断的添加,假设答案有错误,希望大家能够指正 1.简述Activity的生命周期 当Activity開始启动的时候,首先调用onCre ...
- Vim 批量替换
假设在非Win系统下. 想批量替换文本不再是Ctrl+F那么简单了, 一般用Vim来做批量替换, 略微复杂点: 比如将192.168.0.1替换为192.168.0.2 :%s/192.168.0.1 ...
- hdu_1166,线段树单点更新
在刷线段树,参考自http://www.notonlysuccess.com/index.php/segment-tree-complete/ #include<iostream> #in ...
- Windows10+VS2013+caffe+Python2.7+CUDA8.0 部署配置
所需环境工具: 1. Windows 10 2. VS2013 3. Windows版本的caffe工具包,地址:https://github.com/Microsoft/caffe 4. Anaco ...
- 13.C语言隐藏黑窗口
//预编译,linker链接,Windows模式 #pragma comment(linker,"/subsystem:\"windows\" /entry:\" ...
- BZOJ 1001 平面图与对偶图的转化 最短路Or最大流
思路: 1.按照题意求最小割 转换成最大流用Dinic解 2. 转换成对偶图 求最短路 Dinic: //By SiriusRen #include <queue> #include &l ...
- Kali linux 2016.2(Rolling)里Metasploit的常用模块
端口扫描 auxiliary/scanner/portscanscanner/portscan/ack ACK防火墙扫描scanner/portscan/ftpbounce FTP跳端口扫描scann ...
- 【DNN控件】
<dnn:DNNDataGrid ID="show" runat="server" DataSourceID="ObjectDataSource ...