NOI 2017 蚯蚓排队 题解
Problem
Meaning
给定一些数字,对它们进行首尾相接和断开两种操作。对于每次询问,求对于每个数字,其后长度一定的数字串在给定数字串中出现的次数,并给出这些次数之积。
Soultion
对于每次首尾相接或断开的操作,如果直接对断点或合点两侧的整个数字串进行操作,时间复杂度不可接受。由于每次查询只有向后 \(k\) 数字串会产生贡献,所以假设 \(k\) 一定,则只需要对断点或合点左侧 \(k-1\) 个数字进行操作。这道题的向后 \(k\) 数字串的长度极为有限,所以当断点或合点左侧最靠近断点或合点的数字是需要修改的数字的第 \(i\) 个后继时,我们即使在每次操作时对每一个需要修改的数字修改它的向后 \(i+2\) 到 \(50\)( \(k\) 的上界)数字串,也不会产生过大的时间开销。
在具体的操作过程中,我们可以取出以断点或合点为圆心,以 \(50\) 为半径的圆内的点,对断点或合点左侧的数字枚举向后数字串的长度记录这个数字串并累加它的出现次数即可。
为了方便取出这些圆上的点,我们可以使用链表对每个数字的前驱与后继进行记录,在对数字串进行操作的时候一并操作。
只需要取以断点或合点为圆心,以 $50$ 为半径的圆内的点的原因
当左侧一个数字的第 \(i-1\) 个后继在断点或合点右侧时这个数字的向后 \(i\) 数字串才会改变,所以左侧只需取 \(49\) 个点。
而即使是断点或合点左侧最靠近断点或合点的数字,也只需要最多 \(49\) 个右侧的数为它做出贡献,所以只需要取圆内的点,而不需要圆上与圆外的点。
由于在查询操作中需要求出数字串的子串,我们将所有对数字串的操作变为字符串操作。为了避免使用一些常数较大的 STL,考虑用数字代表每个字符串,将每个向后数字串哈希起来代表这个数字串,并使用哈希表记录每个数字串的出现次数,在查询操作时查询每个长度为 \(k\) 的子串的哈希值与对应出现次数并进行求积,即可得到答案。
Code
#include<bits/stdc++.h>
using namespace std;
const unsigned long long mdr=998244353,pp=33557999;
#define numhash(x) (x%pp)
unsigned long long n,m,a[200010],pre[200010],nxt[200010],t[200010];
struct node{
unsigned long long val;
unsigned long long hashv;
int next;
};
struct table{
node data[35000000];
int cnt,head[35000000];
inline unsigned long long& operator [] (unsigned long long x){
int temh=numhash(x);
for(int i=head[temh];i;i=data[i].next){
if(data[i].val==x) return data[i].hashv;
}
data[++cnt]={x,0,head[temh]};
head[temh]=cnt;
return data[cnt].hashv;
}
}mp,str;
int opt,o,p,pos;
string s;
int main(){
scanf("%llu%llu",&n,&m);
t[0]=1;
for(int i=1;i<=n;++i) t[i]=t[i-1]*11;
for(int i=1;i<=n;++i){
scanf("%llu",&a[i]);
++mp[a[i]];
}
for(;m>0;--m){
scanf("%d",&opt);
if(opt==1){
scanf("%d%d",&o,&p);
int lft=49,rgt=50;
unsigned long long tem[150],hs[150];
for(int i=o;i&&lft;i=pre[i],--lft) tem[lft]=a[i];
++lft;
for(int i=p;i&&rgt<99;i=nxt[i],++rgt) tem[rgt]=a[i];
--rgt;
for(int i=lft;i<=rgt;++i) hs[i]=hs[i-1]*11+tem[i];
for(int i=lft;i<50;++i){
for(int len=51-i;len<=min(50,rgt-i+1);++len){
int j=i+len-1;
++mp[hs[j]-hs[i-1]*t[len]];
}
}
nxt[o]=p,pre[p]=o;
}else if(opt==2){
scanf("%d",&o);
p=nxt[o];
int lft=49,rgt=50;
unsigned long long hs[150],tem[150];
for(int i=o;i&&lft;i=pre[i],--lft) tem[lft]=a[i];
++lft;
for(int i=p;i&&rgt<99;i=nxt[i],++rgt) tem[rgt]=a[i];
--rgt;
for(int i=lft;i<=rgt;++i) hs[i]=hs[i-1]*11+tem[i];
for(int i=lft;i<50;++i){
for(int len=51-i;len<=min(50,rgt-i+1);++len){
int j=i+len-1;
--mp[hs[j]-hs[i-1]*t[len]];
}
}
nxt[o]=pre[p]=0;
}else{
cin>>s;
scanf("%d",&o);
int tem=s.length();
for(int i=0;i<tem;++i) str[i+1]=str[i]*11+s[i]-'0';
unsigned long long ans=mp[str[o]]%mdr;
for(int i=o+1;i<=tem;++i) ans=ans*mp[str[i]-str[i-o]*t[o]]%mdr;
printf("%llu\n",ans);
}
}
return 0;
}
NOI 2017 蚯蚓排队 题解的更多相关文章
- [NOI 2017]蚯蚓排队
Description 题库链接 蚯蚓幼儿园有 \(n\) 只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从 \(1\) 到 \(n\) 的连续正整数编号.每只蚯蚓的长度 ...
- 【NOI】2017 蚯蚓排队(BZOJ 4943,LOJ 2303) 模拟+hash
[题目]#2303. 「NOI2017」蚯蚓排队 [题意]给定n条长度不超过6的蚯蚓,初始各自在一个队伍.m次操作:1.将i号蚯蚓和j号蚯蚓的队伍合并(保证i为队尾,j为队首).2.将i号蚯蚓和它后面 ...
- BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
- NOI 2017 Day1 题解
被虐爆了... T1 整数 题目传送门 Description 有一个整数 \(x\),有 \(n\) 此操作,每次操作为以下两种情况: 给出 \(a,b\),将 \(x\) 加上 \(a\times ...
- 【BZOJ4943】【NOI2017】蚯蚓排队(哈希)
[BZOJ4943][NOI2017]蚯蚓排队(哈希) 题面 BZOJ 洛谷 UOJ 题解 记得去年看网络同步赛的时候是一脸懵逼的. 昨天看到\(zsy\)做了,今天就看了看.. 这不是\(Hash\ ...
- LOJ2303 「NOI2017」蚯蚓排队
「NOI2017」蚯蚓排队 题目描述 蚯蚓幼儿园有$n$只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从$1$到$n$的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示 ...
- NOI 2017滚粗退役记
NOI 2017 游记 又到了OIer退役了的季节 Day -1 今天是报到日. 中午11点多的动车.动车上和dick32165401和runzhe2000谈笑风生.顺便用dick32165401的流 ...
- 「NOI2017」蚯蚓排队 解题报告
「NOI2017」蚯蚓排队 这题真的草 你考虑\(k\)这么小,每次合并两个串,增加的有用串的数量是\(O(k^2)\)的,暴力加入这些串,求一下这些串的Hash值,塞到Hash表里面去 这里采用类似 ...
- [NOI2017]蚯蚓排队 hash
题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...
- World Finals 2017 (水题题解)
看大佬做2017-WF,我这种菜鸡,只能刷刷水题,勉强维持生活. 赛后补补水题. 题目pdf链接,中文的,tls翻译的,链接在这里 个人喜欢在vjudge上面刷题. E Need for Speed ...
随机推荐
- [源码系列:手写spring] IOC第四节:Bean属性注入
主要内容 添加PropertyValue类表示Bean的属性. 为Bean定义对象BeanDefinition添加PropertyValues列表用来存储Bean的各种属性. Bean实例化时根据Pr ...
- Visual Studio Browser Link
用Visual Studio 2013 | 2015(不知道其他版本会不会)创建的项目(WebForm & MVC), 直接运行访问的页面源码会出现如下内容: 而这个莫名其妙多出来的Visua ...
- C#连接小智服务器并将音频解码播放过程记录
前言 最近小智很火,本文记录C#连接小智服务器并将音频解码播放的过程,希望能帮助到对此感兴趣的开发者. 如果没有ESP-32也想体验小智AI,那么这两个项目很适合你. 1.https://github ...
- MySurvey 问卷调查, 一个简单的Biwen.QuickApi示例项目
MySurvey 项目 很久没更新我的博客了,之前开发的Biwen.QuickApi微框架 一直没有开发一个示例项目,最近有点时间,写了一个示例项目稍微介绍下 项目简介 这是一个基于 Biwen.Qu ...
- 11. RabbitMQ 消息队列 Federation (Exchange 交换机和 Queue队列) + Shovel 同步的搭建配置
11. RabbitMQ 消息队列 Federation (Exchange 交换机和 Queue队列) + Shovel 同步的搭建配置 @ 目录 11. RabbitMQ 消息队列 Federat ...
- 一句话秒建公网站!AI边缘计算颠覆传统开发
一句话就能让 AI 搭建一个公网可访问的完整网站: 短短几秒钟内,AI 便能完成所有构建操作: 这或许是目前全球最简便的建站方案: 本文使用的 AI 工具为腾讯云的 EdgeOne Pages MCP ...
- Python科学计算系列6—积分
1.定积分 例1:求下列函数的定积分 代码如下: from sympy import * x = symbols('x') f = integrate(exp(-x), (x, 0, oo)) pri ...
- 解释Spring框架中bean的生命周期
一.Bean生命周期的流程图 二.spring的生命周期 spring生命周期中的阶段,包括初始化.使用.销毁. 1.初始化阶段 1)调用bean的构造函数,创建实例: 2)进行参数依赖注入: 3)若 ...
- jstree上手文档 [初始化时默认选中、全部展开、获取实例的数据等问题]
jstree官网:https://www.jstree.com/ ------------------- 实例化tree .jstree() 默认样式: var container = $('#xxx ...
- sonarqube+gitlab+jenkins+maven集成搭建 (五)
Jenkins与SonarQube Jenkins 配置 SonarQube在 SonarQube 中生成 Server authentication token登录 SonarQube 后,在 &q ...