【数据结构】子序列自动机
子序列自动机
这东西是我刷 ARC 的时候遇到的,慕名而来。
结合模板题阅读:
https://www.luogu.com.cn/problem/P5826
构建
这个自动机原理十分简单,你可以将它当作一个 dp 来食用:
记所给的字符串为 ,字符集为 , 为第 个字符之后(不包括位置 )字符 所在的最近的位置。
那么我们有转移方程:
注意到转移的方向,我们只需要倒序扫一遍字符串并构建 即可。
优化
当字符集 大小 很小的时候,直接转移就够了。
那, 比较大的时候如何处理呢?
注意到对于上面的转移方程,其实只有字符 的时候 才会被更新,那么我们不妨将 看成是一个桶(值域是字符集),则我们需要做的操作就是在桶的位置 作单点修改。
而因为我们需要开 (字符串 长度)次桶,每次都相应地作单点修改,因此这一过程可以用主席树来维护。
查询是否存在所求子序列
由 构建过程知这是基于贪心的思想构建的,所以我们将待查询的串 扔到 上并根据查询串的字符作转移,如果跳出去了就肯定没有,反之必然有,复杂度 。
也就是本模板题,代码见下面的实现。
实现
截至目前,洛谷最优解有五页,我排到第四页,QAQ。
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;
inline void read(int &x){
int s=0; x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=1e5+5;
struct Node{
int l, r;
int go;
}tr[N*25];
int root[N], idx;
int qwq, n, q, m;
int w[N];
void upd(int &p, int q, int l, int r, int x, int k){
p=++idx;
tr[p]=tr[q];
if(l==r){;
tr[p].go=k;
return;
}
int mid=l+r>>1;
if(x<=mid) upd(tr[p].l, tr[q].l, l, mid, x, k);
else upd(tr[p].r, tr[q].r, mid+1, r, x, k);
}
void build(){
dwn(i,n,1) upd(root[i-1], root[i], 1, m, w[i], i);
}
int query(int u, int l, int r, int x){
if(l==r) return tr[u].go;
int mid=l+r>>1;
if(x<=mid) return query(tr[u].l, l, mid, x);
return query(tr[u].r, mid+1, r, x);
}
int main(){
cin>>qwq>>n>>q>>m;
rep(i,1,n) read(w[i]);
build();
while(q--){
int k; read(k);
bool ok=true;
int u=0;
while(k--){
int x; read(x);
auto go=query(root[u], 1, m, x);
if(!go) ok=false;
if(ok) u=go;
}
puts(ok? "Yes": "No");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2021-03-29 AtCoder Beginner Contest 100 题解