题目描述#

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

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

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

共有两种操作。

第一种操作:

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

第二种操作:

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

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

对于\(∀i∈[1,l]\)有\(T_{T.size−l+i}≠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≤10^6,m≤3.3333×10^4,|∑|≤10^3,S_i∈[1,|∑|]。(∑表示字符集)\)

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

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

\(subtask3(20\%):|∑|≤2∣\)

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

样例解释:#

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

\(l=1\)时\(T[1]=S[1]\),所以答案为\(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\)


\(PS:\) 以下是我们机房的一个蒟蒻(文化课大佬%%%)lqx在博主的指导下撰写的。###

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

预计得分\(17pts\)。

对于\(O(m^2)\)的做法,因为这个题实际上是查找\(S\)的前\(l\)个和\(T\)的后\(l\)个是否每个都不相等,我们考虑记录\(dp[l]\)表示在上述意义下\(l\)是否合法(\(0\)表示都不相等,\(1\)表示至少有一个等)。容易知道,在\(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\)串最前面插入一个字符时,因为原本的\(i\)个后缀依然没有变化,只是增加了一个新的后缀\(i+1\),所以我们只需暴力\(check\)新加入的后缀,对于每一位枚举是否有相等的即可。

时间复杂度\(O(m^2)\),预计得分\(50pts\)。

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

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

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

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

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

在\(T\)串头部插入新字符时,我们将问题拆成两部分:

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

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

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

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

考虑如何进行这样的操作。假设\(x\)是在第\(i\)位加入队列并且对应的\(ch\)值在第\(k\)位上是\(1\),\(dp[i-1+k]\)一定不合法(假设没有从后插入的)。这时\(x\)距离队尾的距离是\(i−1\),所以当\(x\)取到\(k\)时,队尾应该到\(k+(i-1)\)位,但是注意在\(bitset\)里是反着存的,所以:

\(dp=dp|(ch[x]<<i−1)\)

时间复杂度为\(O(\dfrac{m^2}{w})\)

代码实现:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<ctime>
#include<climits>
#include<algorithm>
#include<bitset>
using namespace std;
const int M=40000;
bitset<M> ch[1010],dp,limit;
int n,m;
int main()
{
int i,t,x;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++) scanf("%d",&x),ch[x].set(i);
for(;i<=n;i++) scanf("%d",&x);
limit.set();
for(i=1;i<=m;i++)
{
scanf("%d%d",&t,&x);
limit.reset(i);
if(t==0) dp=(dp<<1)|ch[x];
else dp=dp|(ch[x]<<i-1);
printf("%d\n",(~(dp|limit)).count());
}
return ~~(0-0);
}

【CSGRound2】逐梦者的初心(洛谷11月月赛 II & CSG Round 2 T3)的更多相关文章

  1. 【LGR-061】洛谷10月月赛 II & X Round 4 Div.1&Div 2

    X Round的题目质量还是一如既往的高 然而每次周末我都要写作业没法用心打233主要是被陈指导放了鸽子 占坑代填(最近坑开的有点多)

  2. 【LGR-054】洛谷10月月赛II

    [LGR-054]洛谷10月月赛II luogu 成功咕掉Codeforces Round #517的后果就是,我\(\mbox{T4}\)依旧没有写出来.\(\mbox{GG}\) . 浏览器 \( ...

  3. 「P4996」「洛谷11月月赛」 咕咕咕(数论

    题目描述 小 F 是一个能鸽善鹉的同学,他经常把事情拖到最后一天才去做,导致他的某些日子总是非常匆忙. 比如,时间回溯到了 2018 年 11 月 3 日.小 F 望着自己的任务清单: 看 iG 夺冠 ...

  4. 「P4994」「洛谷11月月赛」 终于结束的起点(枚举

    题目背景 终于结束的起点终于写下句点终于我们告别终于我们又回到原点…… 一个个 OIer 的竞赛生涯总是从一场 NOIp 开始,大多也在一场 NOIp 中结束,好似一次次轮回在不断上演.如果这次 NO ...

  5. 「LuoguP4995」「洛谷11月月赛」 跳跳!(贪心

    题目描述 你是一只小跳蛙,你特别擅长在各种地方跳来跳去. 这一天,你和朋友小 F 一起出去玩耍的时候,遇到了一堆高矮不同的石头,其中第 ii 块的石头高度为 h_ihi​,地面的高度是 h_0 = 0 ...

  6. 洛谷10月月赛II题解

    [咻咻咻] (https://www.luogu.org/contestnew/show/11616) 令人窒息的洛谷月赛,即将参加NOIp的我竟然只会一道题(也可以说一道也不会),最终145的我只能 ...

  7. 洛谷11月月赛(284pts rank85)

    https://www.luogu.org/contestnew/show/12006 我是比赛完后在去写的 这是我第一次打洛谷月赛,之前一次是比赛完才去看而且写了第一题就没写后面的了 284分,太水 ...

  8. 洛谷11月月赛round.2

    P3414 SAC#1 - 组合数 题目背景 本题由世界上最蒟蒻最辣鸡最撒比的SOL提供. 寂月城网站是完美信息教室的官网.地址:http://191.101.11.174/mgzd . 题目描述 辣 ...

  9. 洛谷11月月赛round.1

    太感动了#2 thwfhk 240 (801ms) 100 100 40   又一张明信片,话说10月的怎么还没收到   P2246 SAC#1 - Hello World(升级版) 题目背景 一天, ...

随机推荐

  1. c#栈的用法

    栈是一种重要的线性结构,栈和队列是限定插入和删除只能在表的“端点”进行的线性表 –栈的元素必须“后进先出”. –栈的操作只能在这个线性表的表尾进行. –注:对于栈来说,这个表尾称为栈的栈顶(top), ...

  2. html 显示 pdf

    html 显示 pdf文件四种方式: 1. <embed src="pdf/wobu.pdf" type="application/pdf" width= ...

  3. 【转】socket通信-C#实现tcp收发图片音视频等字节流数据

    在日常碰到的项目中,经常碰到需要收发二进制数据的场景.比如要发送一张图片,要发送一首音频,要发送一个压缩包,要发送一个视频等等.这些数据并非字符串,而是二进制字节流数据.那么如何如何使用SharpSo ...

  4. spring mvc 服务器端输出一条可执行js

    @RequestMapping(value = "/test",produces = "text/html; charset=UTF-8") @Response ...

  5. windows下vmware和Hyper-v共存方法

    问题描述:环境:windows server 2012 r2系统下安装Hyper-v后,再安装Vmware 在Vmware中创建虚拟机,安装虚拟机系统的时候,vmware提示:VMware Works ...

  6. 在python当中使用redis

    redis数据库 # 1.安装redis与可视化操作工具 # 2.在服务中管理redis服务器的开启关闭 # 3.命令行简单使用redis: -- redis-cli # 启动客户端 -- set k ...

  7. BeanPostProcessor后置处理器原理以及ApplicationListener原理

    BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的 1.BeanFactoryPostProcessor:BeanFactory的后置处理器; 在Bean ...

  8. 简述mysql问题处理

    最近,有一位同事,咨询我mysql的一点问题, 具体来说, 是如何很快的将一个mysql导出的文件快速的导入到另外一个mysql数据库.我学习了很多mysql的知识, 使用的时间却并不是很多, 对于m ...

  9. centos7修改网卡命名规则

    实验目的: 修改默认的网卡命名规则,习惯于ethx的形式 实验环境: centos7 熟悉控制网卡名字的规则生产的参数biosdevname/net.ifnames   /etc/default/gr ...

  10. jperf windows

    jperf windows版是款简单实用的网络性能测试的工具:它也是款图形界面的iperf程序,可以这进行使用JPerf程序的时候,快速的进行简化您的命令行参数,而且这进行测试结束之后,还是以图形化的 ...