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]分别代表拥 ...
随机推荐
- LeetCode【8】. String to Integer (atoi) --java实现
String to Integer (atoi) Implement atoi to convert a string to an integer. Hint: Carefully consider ...
- js 使用(不断更新...)
1.JS 对象(Object)和字符串(String)互转 var jsObj = {}; jsObj.testArray = [1, 2, 3, 4, 5]; jsObj.name = 'CSS3' ...
- FZOJ--2214--Knapsack problem(背包)
Problem 2214 Knapsack problem Accept: 5 Submit: 8 Time Limit: 3000 mSec Memory Limit : 32768 K ...
- [USACO09JAN] 气象测量/气象牛The Baric Bovine 解题报告(DP)
题目链接:https://www.luogu.org/problemnew/show/P2933 Description 为了研究农场的气候,Betsy帮助农夫John做了N(1 <= N &l ...
- 【转】android新组件RecyclerView使用介绍和进阶使用,替用Gallery
简介: RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用 ...
- C++字节对齐与结构体大小计算
转载注明出处:http://pppboy.blog.163.com/blog/static/30203796201082494026399/ 感谢原创博主的辛勤成果. 说明: 结构体的sizeof值, ...
- SqlServer 删除日志
1 数据库在使用过程中会使日志文件不断增加,使得数据库的性能下降,并且占用大量的磁盘空间.SQL Server数据库都有log文件,log文件记录用户对数据库修改的操作.可以通过直接删除log文件和 ...
- P3157 [CQOI2011]动态逆序对 CDQ分治
一道CDQ分治模板题简单来说,这道题是三维数点对于离线的二维数点,我们再熟悉不过:利用坐标的单调递增性,先按更坐标排序,再按纵坐标排序更新和查询时都直接调用纵坐标.实际上,我们是通过排序将二维中的一维 ...
- yii2.0缓存篇之文件缓存
文件缓存: 在 frontend/config/main.php/components数组下添加: 'cache'=>[ 'class'=>'yii\caching\FileCa ...
- HDFS 文件系统流程图。PB级文件存储时序图。
大小文件通吃, 热点hash功能. 全局唯一KV索引. 百度网盘模式.断点续传功能.MR分析功能. 来自为知笔记(Wiz)