题目背景

由于Y校的老师非常毒瘤,要求\(zhouwc\)在\(csp\)考前最后\(3\)天参加期中考,\(zhouwc\)非常生气,决定消极考试,以涂完卡但全错为目标。现在\(retcarizy\)看\(zhouwc\)太可怜了,想要帮\(zhouwc\)解决一个问题,但他自己又太忙了,咕咕咕,于是就把问题甩给了你。

题目描述

给你一个长度为\(n\)的字符串\(S\)。

有\(m\)个操作,保证\(m\leq n\)。

你还有一个字符串\(T\),刚开始为空。

共有两种操作。

第一种操作:

在字符串\(T\)的末尾加上一个字符。

第二种操作:

在字符串\(T\)的开头加上一个字符。

每次操作完成后要求输出有几个\(l \in [1,T.size]\)满足以下条件:

对于\(\forall i \in [1,l]\)有\(T_{T.size-l+i} \ne S_{i}\)

\(Tip:\)字符串下标从\(1\)开始。\(T.size\)表示\(T\)的长度。

输入格式

第一行两个正整数\(n,m\)。

第二行\(n\)个正整数,用空格隔开,第\(i\)个整数表示\(S_i\)。

接下来\(m\)行,每行两个数字\(opt,ch\),\(opt=0\)表示在\(T\)的末尾加一个字符\(ch\),\(opt=1\)表示在\(T\)的开头加一个字符\(ch\)。

输出格式

共\(m\)行,每行一个非负整数表示第\(m\)操作后的输出。

输入输出样例

输入 #1

10 3
1 2 3 1 2 3 2 3 2 3
0 1
1 2
0 3

输出 #1

0
1
1

说明/提示

注意:本题采用捆绑测试,只有当你通过一个subtask的所有点后,你才能拿到这个subtask的分数

对于所有的数据 \(n \leq 10^6,m \leq 3.3333 \times 10^4,|\sum|\leq10^3,S_i \in [1,|\sum|]\)(\(\sum\)表示字符集)

\(subtask1(17\%)\):\(m \leq 333\)

\(subtask2(33\%):m \leq 3333\)

\(subtask3(20\%):|\sum|\leq2∣\)

\(subtask4(30\%):\)无特殊条件

样例解释:

第一次操作后,\(T=“1”\),

\(l=1\)时\(T[1]=S[1]\),所以答案为你不jjgvfj\(0\)

第二次操作后,\(T=“21”\),

\(l=1\)时,\(T[2]=S[1]\)

\(l=2\)时,\(T[1]!=S[1]\),\(T[2]!=S[2]\),所以答案为\(1\)

第三次操作后,\(T=“213”\),

\(l=1\)时,\(T[3]!=S[1]\);

\(l=2\)时,\(T[2]=S[1]\);

\(l=3\)时,\(T[3]=S[3]\),所以答案为\(1\)

\(O(m^3)\)的做法很容易想,按照题意模拟即可。预计得分\(17pts\)。

对于\(O(m^2)\)的做法,因为这个题实际上是查找\(S\)的前\(l\)个和\(T\)的后\(l\)个是否严格不相等,我们考虑记录\(dp[l]\)表示在上述意义下\(l\)是否合法。容易知道,在\(T\)串最后插入一个字符时,因为\(S\)串始终不变,\(T\)串的最后\(l\)个字符从原本\(T\)串的后\(l\)个字符变成了原本\(T\)串的后\(l-1\)个字符加上新加入的字符,所以为了比较新的\(T\)串后\(l\)个字符是否合法,我们只需要比较新字符、原本\(T\)串的后\(l-1\)个字符是否相等即可。即\(dp[i]=dp[i-1]|(ch==S[i])\)。这样,对于每个加入的字符,只需要用\(O(1)\)的复杂度检查每个枚举到的\(l\)是否合法即可。

在\(T\)串最前面插入一个字符时,因为原本所有的合法的\(l\)依然没有变化,只是增加了一个新的\(l\),所以我们只需暴力\(check\)新加入的答案\(l\),对于每一位枚举是否不同即可。

时间复杂度\(O(m^2)\),预计得分\(50pts\)。是我在考场上想出来的方法。

考虑优化\(O(m^2)\)的做法,我们找到了状压神器——\(bitset\),它可以将复杂度优化到原来的\(\frac{1}{32}\)。如果常数优秀一些这个方法可以过。

考虑刚才的方法算过了哪些不可能合法的状态,我们知道所有的字符其存在位置都是独立的,所以我们用一个\(bitset\)数组\(id[i]\)记录字符\(i\)在哪些位置上出现过。只要加入的新数\(dt\)对应的位置是\(id[dt]\)上\(1\)的位置,则该状态肯定不合法。

所以这样优化的关键在于同时算出了所有合法的状态。所以我们用\(f\)的第\(i\)位的\(0/1\)表示后缀长度为\(i\)时是否合法。

如果在\(T\)串尾部加入新的字符,则对于长度是\(i\)的情况一定是由\(i-1\)的情况和新加入位的情况同时转移来(见上述\(O(n^2)\)做法),而所有新加入的位对应与\(S\)串中哪些位相同已经存储好,假设加入的字符是\(dt\),则\(f=(f<<1)|id[dt]\)。

如果在\(T\)串头部加入新的字符,设原来\(T\)串有效的后缀长度有\(l\)位,则新的\(T\)串后\(l\)位是否合法状态不变,所以新旧\(T\)串前面\(l\)位答案一样;

在\(T\)串头部插入新字符时,我们发现遇到了一些新的问题:

第一,我们发现在头部加入字符时,后面的所有字符都往后移了一位。

第二,我们需要比较加入的新字符和第一个字符是否相同。

很明显困难在于解决第一个问题。因为我们如果要想比较移动之后的字符和\(S\)的关系,在不知道其它任何东西的情况下,需要另用一个\(O(n)\)检查。

解决这个问题的方法是一个非常重要的思想:费用提前。在每次从队尾加入一个字符时,我们将这个字符所能贡献到答案的所有位置一次存好。方法很简单,假设我们每次加进的字符是\(dt\),考虑这一位对应到\(S\)串的所有可能。如果\(dt\)对应到的某一位上\(id[dt]\)在同样的位上恰好是\(1\),说明当队尾不断加入字符使当前这个\(dt\)恰好对应到刚才说的这一位上,则这样的方案肯定是不合法的。

考虑如何进行这样的操作。假设\(dt\)是在第\(i\)位加入队列,则\(dt\)离\(T\)结尾的长度是\(i-1\)。注意这里我们只讨论\(T\)序列结尾的费用提前,因为其它点情况和结尾一样。假设\(dt\)对应的\(id\)值在第\(k\)位上是\(1\),说明\(dt\)在取到第\(k\)位时整体一定不合法。这时\(dt\)距离队尾的距离是\(l-1\),所以\(dt\)的位置由队尾左移\(i-1\)位得到,所以当\(dt\)取到\(k\)时,队尾应该取到\(k+l-1\)位,但是注意是反着存的,所以:

\[f=f|(id[dt]<<x-1)
\]

上代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<bitset>
using namespace std;
int n,m,opt,S[1000005],dt;
bitset<35005> f,id[1005],now;
int read(){
int ans=0;
char ch=getchar();
while(ch<'0'||ch>'9')
ch=getchar();
while(ch<='9'&&ch>='0'){
ans=ans*10+ch-'0';
ch=getchar();
}
return ans;
}
int main(){
n=read();
m=read();
for(int i=1;i<=n;i++)
S[i]=read();
for(int i=1;i<=m;i++)
id[S[i]].set(i);
now.set();
for(int i=1;i<=m;i++){
opt=read();
dt=read();
now.reset(i);
if(opt==0)
f=(f<<1)|id[dt];
else
f=f|(id[dt]<<(i-1));
printf("%d\n",(~(f|now)).count());
}
return 0;
}

2019.11.11 洛谷月赛t3的更多相关文章

  1. 【洛谷】【洛谷月赛】4月月赛Round 1/2

    洛谷月赛“月”来“月”丧了,一月更比一月丧,做得我十分不“月”…… 4月的两轮月赛,都只会T1,就写一下吧,等待后续更新…… 先看看Round1的T1: [R1T1] 网址:点我 [题意简述] 给定一 ...

  2. 洛谷 p6858 深海少女与胖头鱼 洛谷月赛 期望dp

    洛谷10月月赛 2 t2 深海少女与胖头鱼 题目链接 参考资料:洛谷10月赛2讲评ppt; 本篇题解考完那天就开始写,断断续续写到今天才写完 本题作为基础的期望dp题,用来学习期望dp还是很不错的 ( ...

  3. 求x!在k进制下后缀零的个数(洛谷月赛T1)

    求x!在k进制下后缀和的个数 20分:     求十进制下的x!后缀和的个数 40分: 高精求阶乘,直接模拟过程 (我不管反正我不打,本蒟蒻最讨厌高精了) 60分     利用一个定理(网上有求x!在 ...

  4. Solution -「JSOI 2019」「洛谷 P5334」节日庆典

    \(\mathscr{Description}\)   Link.   给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的).   \(|S|\le3\time ...

  5. 2018.11.09 洛谷P1110 [ZJOI2007]报表统计(multiset)

    传送门 sb题. 直接用两个multisetmultisetmultiset维护相邻两个数的差值和所有数的前驱后继. 插入一个数的时候更新一下就行了. 代码: #include<bits/std ...

  6. 2018.11.06 洛谷P1099 树网的核(最短路+枚举)

    传送门 之前看李煜东的书一直感觉是道神题. 然后发现这题数据范围只有300?300?300? 直接上floydfloydfloyd然后暴力就完了啊. 代码: #include<bits/stdc ...

  7. 2018.11.06 洛谷P1941 飞扬的小鸟(背包)

    传送门 上升看成完全背包. 下降看成01背包. 注意边界转移就行了. 代码: #include<bits/stdc++.h> using namespace std; inline int ...

  8. 2018.11.04 洛谷P2679 子串(线性dp)

    传送门 为什么前几年的noipnoipnoip总是出这种送分题啊? 这个直接线性dpdpdp不就完了吗? f[i][j][k][0/1]f[i][j][k][0/1]f[i][j][k][0/1]表示 ...

  9. 2018.11.04 洛谷P1081 开车旅行(倍增)

    传送门 思路简单码量超凡? 感觉看完题大家应该都知道是倍增sbsbsb题了吧. 首先预处理出从每个点出发如果是AAA走到哪个点,如果是BBB走到哪个点. 然后利用刚刚预处理出的信息再预处理从每个点出发 ...

随机推荐

  1. 栈二:包含min函数的栈

    /** * 题目:包含min函数的栈 * 描述:  定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数.  *  注:用data来保存数据,用另一个栈min保存依次入栈最小的数 *  ...

  2. python语言程序设计基础(嵩天)第二章课后习题

    p56: *2.1 实例1的修改.改造实例代码1.1,采用eval(input(<提示内容>))替换现有输入部分,并使输出的温度值为整数. 源代码: TempStr=input(" ...

  3. Java8新特性时间日期库DateTime API及示例

    Java8新特性的功能已经更新了不少篇幅了,今天重点讲解时间日期库中DateTime相关处理.同样的,如果你现在依旧在项目中使用传统Date.Calendar和SimpleDateFormat等API ...

  4. LeetCode_844-Backspace String Compare

    输入两个字符串S和T,字符串只包含小写字母和”#“,#表示为退格键,判断操作完退格键剩下字符串是否相等例子:S = “ab#c", T = "ad # c” 返回true,剩下的字 ...

  5. 微信开发中使用微信JSSDK和使用URL.createObjectURL上传预览图片的不同处理对比

    在做微信公众号或者企业微信开发业务应用的时候,我们常常会涉及到图片预览.上传等的处理,往往业务需求不止一张图片,因此相对来说,需要考虑的全面一些,用户还需要对图片进行预览和相应的处理,在开始的时候我使 ...

  6. Python3 解决 ModuleNotFoundError: No module named 'pygal.i18n' 问题

    在获取国别码集通过导入模块pygal报以下问题: from pygal.i18n import COUNTRIES  解决方法: 安装模块 pip3 install pygal_maps_world ...

  7. top命令之性能分析

    top命令详解 当前时间20:27:12 当前系统运行时间3:18秒    1个用户   系统负载平均长度为0.00,0.00,0.00(分别为1分钟.5分钟.15分钟前到现在的平均值) 第二行为进程 ...

  8. python requests简单接口自动化

    get方法 url:显而易见,就是接口的地址url啦 headers:定制请求头(headers),例如:content-type = application/x-www-form-urlencode ...

  9. PHP reset

    1.函数的作用:重置数组内部指针,并返回第一个元素 2.函数的参数: @param array  $array 3. 例子一: <?php $arr1 = []; $arr2 = [false, ...

  10. [牛客网NOIP赛前集训营-普及组(第二场)]D-合法括号序列

    链接:https://www.nowcoder.com/acm/contest/165/D来源:牛客网 合法括号序列 键盘上有左括号(,右括号),和退格键-,共三个键. 牛牛希望按键n次,使得输入的字 ...