首页 > 其他分享 >P5826 【模板】子序列自动机

P5826 【模板】子序列自动机

时间:2022-10-29 18:35:13浏览次数:89  
标签:10 询问 leq P5826 序列 自动机 模板 define

题目链接

P5826 【模板】子序列自动机

【模板】子序列自动机

题目背景

本题中,若 \(x\) 是 \(y\) 的子序列,则等价于存在一个单调递增序列 \(z\),满足 \(|z| = |x|\),\(z_{|x|} \leq |y|\),且 \(\forall i \in [1, ~|x|],~y_{z_i} = x_i\)。其中 \(|x|,~|y|,~|z|\) 分别代表序列 \(x,~y,~z\) 的长度,\(x_i,~y_i,~z_i\) 分别代表序列 \(x,~y,~z\) 的第 \(i\) 项。

这是一道在 yLOI2020 备选题里被毙掉的题目。

题目描述

给定一个长度为 \(n\) 的正整数序列 \(a\) ,有 \(q\) 次询问,第 \(i\) 次询问给定一个长度为 \(L_i\) 的序列 \(b_i\),请你判断 \(b_i\) 是不是 \(a\) 的子序列。序列 \(a\) 和所有 \(b_i\) 中的元素都不大于一个给定的正整数 \(m\)。

输入格式

每个测试点有且仅有一组数据。

输入的第一行是四个用空格隔开的整数,分别代表 \(type,~n,~q,~m\)。其中 \(type\) 代表测试点所在的子任务编号,其余变量的含义见【题目描述】。

输入的第二行是 \(n\) 个用空格隔开的整数,第 \(i\) 个数字代表序列 \(a\) 的第 \(i\) 个元素 \(a_i\)。

第 \(3\) 行至第 \((q + 2)\) 行,每行代表一次询问。第 \((i + 2)\) 行的输入格式为:

  • 第 \((i + 2)\) 行的行首有一个整数 \(l_i\),代表第 \(i\) 次询问的序列长度。一个空格后有 \(l_i\) 个用空格隔开的整数。该行的第 \((j + 1)\) 个整数代表序列 \(b_i\) 的第 \(j\) 个元素 \(b_{i, j}\)。

输出格式

对于每次询问,输出一行一个字符串,若给定的序列是 \(a\) 的子序列,则输出 Yes,否则输出 No

样例 #1

样例输入 #1

0 5 5 5
1 3 2 2 4
3 1 5 2
2 3 2
3 1 2 3
3 1 2 4
5 1 3 2 2 4

样例输出 #1

No
Yes
No
Yes
Yes

提示

样例 1 解释

  • 对于第一次询问,原序列中没有 \(5\),所以给定序列显然不是原序列的子序列。
  • 对于第二次询问,存在两个合法的序列 \(z\),分别是 \(\{2,~3\}\) 和 \(\{2,~4\}\)。即 \(a_{2} = b_{2, 1},~a_3 = b_{2, 2}\) 或 \(a_2 = b_{2, 1},~a_{4} = b_{2, 2}\)。这里 \(b_{i, j}\) 代表序列 \(b_i\) 的第 \(j\) 个元素,序列 \(z\) 的含义见【题目背景】,下同。
  • 对于第三次询问,不存在合法的序列 \(z\)。
  • 对于第四次询问,存在两个合法的序列 \(z\),分别是 \(\{1,~3,~5\}\) 和 \(\{1,~4,~5\}\)。
  • 对于第五次询问,存在一个合法的序列 \(z\),为 \(\{1,~2,~3,~4,~5\}\)。

数据范围与约定

本题采用多测试点捆绑测试,共有 3 个子任务

  • Subtask 1(20 points):\(type = 1\),\(n, q, m \leq 100\),\(\sum_{i = 1}^{q} l_i \leq 10^3\)。
  • Subtask 2(35 points):\(type = 2\),\(n,q \leq 10^5\),\(m \leq 26\),\(\sum_{i = 1}^{q} l_i \leq 10^6\)。
  • Subtask 3(45 points):\(type = 3\),\(n,q,m \leq 10^5\),\(\sum_{i = 1}^q L_i \leq 10^6\)。

对于全部的测试点,保证 \(1 \leq n, m, q \leq 10^5\),\(1 \leq a_i, b_{i, j} \leq m\),\(1 \leq l_i \leq 10^6\),\(\sum_{i = 1}^{q} l_i \leq 10^6\)。

提示

  • 请注意常数因子对程序效率造成的影响。

  • 本题输入规模较大,请注意数据读入对程序效率造成的影响。

  • 请注意输入第一行的顺序为先输入询问次数 \(q\),再输入序列元素最大值 \(m\)。

解题思路

序列自动机

  • 时间复杂度:\(O()\)

二分

将 \(a\) 的下标用桶存下来,每次读入子序列时,都从当前值满足条件的最前面开始搜索,如果搜不到则一定不是子序列

  • 时间复杂度:\(O(\sum_{i=1}^q l_i \times logn)\)

代码

  • 序列自动机

  • 二分
// Problem: P5826 【模板】子序列自动机
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P5826
// Memory Limit: 500 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1e5+5;
vector<int> a[N];
int main()
{
    int t,n,q,m,x,l;
    scanf("%d%d%d%d",&t,&n,&q,&m);
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&x);
    	a[x].pb(i);
    }
    while(q--)
    {
    	bool res=true;
    	int pos=0;
    	for(scanf("%d",&l);l;l--)
    	{
    		scanf("%d",&x);
    		pos=upper_bound(a[x].begin(),a[x].end(),pos)-a[x].begin();
    		if(pos<a[x].size())pos=a[x][pos];
    		else
    			res=false;
    	}
    	puts(res?"Yes":"No");
    }
    return 0;
}

标签:10,询问,leq,P5826,序列,自动机,模板,define
From: https://www.cnblogs.com/zyyun/p/16839350.html

相关文章

  • 数据结构模板整合
    栈#include<iostream>#include<cstdio>#definemaxn100010usingnamespacestd;intn,x;template<typenametype>inlinevoidread(type&x){x=0;boolfl......
  • 二分法&三分法模板
    二分法求函数零点longdoublel=INT_MIN,r=INT_MAX,mid,eps=1e-6;while(r-l>eps){ mid=(l+r)/2; if(f(mid)<0)l=mid; elser=mid;}cout<<l<<endl;三分法......
  • 【模板】边双
    这里介绍一种与众不同的写法。前置知识:强联通分量回忆强联通分量的算法过程,我们利用有向图的dfn树将图上的所有边分成四种:树边、前向边、后向边和横向边。其中在原......
  • 二分模板
    二分模板一共有两个,分别适用于不同情况。算法思路:假设目标值在闭区间[l,r]中,每次将区间长度缩小一半,当l=r时,我们就找到了目标值。版本1当我们将区间[l,r]划分成[l,m......
  • 标准模板库 02 容器vector
    容器大致分为序列式容器(Sequence),关联式容器(Associative)和无序容器(Unordered),无序容器也可以归为关联式容器内。序列式容器(Sequence)array:数组,是一种固定大小的结构,静态空......
  • 标准模板库 01 概念
    STL是可复用的标准模板库,在泛性思维上架设的一个概念结构,使抽象概念为主体,并使其系统化。容器(containers):用于存放数据,包含各种如vector,list,deque,set,map等数据结构。分配......
  • P4213 【模板】杜教筛(Sum)
    题目链接P4213【模板】杜教筛(Sum)题目描述给定一个正整数,求\[ans_1=\sum_{i=1}^n\varphi(i)\]\[ans_2=\sum_{i=1}^n\mu(i)\]输入格式本题单测试点内有多组数据。......
  • 考场Dev配置及代码模板
    编译选项:-std=c++14-O2-Wl,--stack=104857600-Wall-Wextra-Wshadow-Wl开大栈空间-Wall显示所有警告-Wextra比较始终为true或始终为false,则发出警告,但不警告常......
  • 洛谷P3391 【模板】文艺平衡树
    题目描述您需要写一种数据结构(可参考题目标题),来维护一个有序数列。其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4] 的话,结果是5 2 ......
  • 递归代码模板--分治代码模板--动态规划的关键
    递归代码模板Pythondefrecursion(level,param1,param2,...):#recursionterminator//递归终结者iflevel>MAX_LEVEL:#process_resu......