题解:P3823 [NOI2017] 蚯蚓排队

news/2025/1/21 11:42:20/文章来源:https://www.cnblogs.com/ezhe/p/18683348

题目链接

https://www.luogu.com.cn/problem/P3823

分析

先解决队伍的合并与分离问题。使用链表结构,分别维护每只蚯蚓的前驱和后继即可。

然后考虑如何统计答案。可以对每只蚯蚓的“向后 \(k\) 数字串”使用字符串哈希的方式获得哈希值,再用一个哈希表存储每个哈希值出现的次数。对于给定的数字串 \(s\) 的每个长度为 \(k\) 的连续子串 \(t\)\(f(t)\) 即为 \(t\) 的哈希值在哈希表中出现的次数。

最后考虑维护每只蚯蚓的“向后 \(k\) 数字串”。

  • \(k=1\) 时,每只蚯蚓的“向后 \(k\) 数字串”是它的长度。
  • \(k \ge 2\) 时,每只蚯蚓的“向后 \(k\) 数字串”只有经历蚯蚓队伍的合并才会形成,只有经历蚯蚓队伍的分离才会消失(即队伍合并是数字串产生的必要不充分条件,队伍分离是数字串消失的必要不充分条件)。具体地,当进行队伍的合并操作时,对于前方队伍中的任何一只蚯蚓,若它的“向后 \(k\) 数字串”跨越了两个队伍,则这条数字串因此次合并而产生,将这个数字串的哈希值在哈希表中的出现次数 \(+1\) 即可。队伍的分离操作同理。

细节内容见代码注释。

Code

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define i64 long long
#define uns unsignedusing namespace std;
using namespace __gnu_pbds;constexpr int N=2e5+5;
int n,m;
char s[int(1e7)+5];namespace Solve{//unordered_map 太慢,使用 pbds 的哈希表 gp_hash_table<uns i64,int>ght;//字符串哈希 constexpr uns i64 p=131;uns i64 pw[int(1e7+5)],hsh[int(1e7+5)];//预处理 void init_pw(int n){pw[0]=1;for(int i=1;i<=n;++i)pw[i]=pw[i-1]*p;return;}//对整个数字串进行哈希 void make_hash(int n,char *s,uns i64 *hash_table){for(int i=1;i<=n;++i)hash_table[i]=hash_table[i-1]*p+s[i]-48;return;}//获取子串的哈希值 uns i64 ask_hash(int l,int r,uns i64 *hash_table){if(l>r)return 0;return hash_table[r]-hash_table[l-1]*pw[r-l+1];}//链表 struct Node{int pre,nxt;//指针域,前驱和后继 int dat;//数据域,蚯蚓的长度 }L[N];//合并 void Union(int p1,int p2){//更新指针 L[p1].nxt=p2,L[p2].pre=p1;//由于题目中 k<=50,拥有跨越两个队伍的数字串的蚯蚓一定不超过 50 个 for(int i=p1,cnt_i=50;(~i)&&(cnt_i)!=0;i=L[i].pre,--cnt_i){uns i64 num_str=0ull;bool flg=false;//数字串长度不超过 50 for(int j=i,cnt_j=50;(~j)&&(cnt_j)!=0;j=L[j].nxt,--cnt_j){num_str=num_str*p+L[j].dat;if(j==p2)flg=true;//开始跨越两个队伍 if(flg)++ght[num_str];}}return;}//分离 void Cut(int p1){int p2=L[p1].nxt;for(int i=p1,cnt_i=50;(~i)&&(cnt_i)!=0;i=L[i].pre,--cnt_i){uns i64 num_str=0ull;bool flg=false;for(int j=i,cnt_j=50;(~j)&&(cnt_j)!=0;j=L[j].nxt,--cnt_j){num_str=num_str*p+L[j].dat;if(j==p2)flg=true;if(flg)--ght[num_str];}}//注意,由于要更新跨越两队伍的数字串的信息,指针的更新要放在后面 L[p1].nxt=L[p2].pre=-1;return;}//统计答案 constexpr i64 mod=998244353;i64 ask_ans(int k,char *s){int len=strlen(s+1);make_hash(len,s,hsh);i64 ans=1;for(int i=k;i<=len;++i){ans=ans*ght[ask_hash(i-k+1,i,hsh)]%mod;if(ans==0)break;}return ans;}
}using namespace Solve;int main(){ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);init_pw(int(1e7));cin>>n>>m;//初始化 for(int i=1;i<=n;++i){cin>>L[i].dat;L[i].pre=L[i].nxt=-1,++ght[L[i].dat];}int op,x1,x2;for(int id_op=1;id_op<=m;++id_op){cin>>op;if(op==1){cin>>x1>>x2;Union(x1,x2);}else if(op==2){cin>>x1;Cut(x1);}else{cin>>(s+1)>>x1;cout<<ask_ans(x1,s)<<'\n';}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/872733.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

语音播报,套件多少异常的问题。(含源代码)

在工作中遇到一家工厂老板的需求:因为产品是有多个配件组成,在生产的时候,经常会多生产,少生产,在组装时,也会出现配件多少的问题,现就此问题设计一款程序。多出,少的,异常的,正常好,会开语音播报。现将全部代码给出以备。 import inspect import os import threadi…

EDMA3学习笔记1

1.1 EDMA3简介 EDMA3(Enhanced Direct Memory Access 3):增强型直接存储器访问的控制器。它是DSP中一个高级数据传输引擎,其结构适合数据的高速传输,可以在没有CPU主要参与的情况下,由控制器完成数据转移,主要服务外部内存(DDR)、片上内存(L2 SRAM)以及串口外设等。…

又一个新项目完结,炸裂!

除了全程直播讲解的、50 个小时的保姆级视频教程之外,我还写了整套文字教程(15 万多字),细致入微!大家好,我是程序员鱼皮。经过了 2 个月的爆肝,我在自己的编程导航的第 11 套有 保姆级教程 的大项目 —— 企业级智能协同云图库平台,完结啦!除了全程直播讲解的、50 个…

kylin V10 SP2 离线单机部署tidb v8.3.0

准备离线组件包 在官方下载页面选择对应版本的 TiDB server 离线镜像包(包含 TiUP 离线组件包)。需要同时下载 TiDB-community-server 软件包和 TiDB-community-toolkit 软件包。 部署离线环境TiUP组件 将离线包传至服务器,执行以下命令安装 TiUP 组件: tar zxvf tidb-comm…

生成型AI应用的质量为何常常不尽人意,以及如何改进

生成型AI应用的质量为何常常不尽人意,以及如何改进2025年,图片来源:elements.envato.com,Marcel Mller 编辑过去两年,生成型AI的热潮席卷了商业世界。这项技术可以提高业务流程的执行效率,减少等待时间,降低过程缺陷。像ChatGPT这样的接口使得与大型语言模型(LLM)的互…

C# WEB API windows server 发布注意事项

1、使用背景: 数据请求方通过接口获取数据,同时使用方通过用户名称进行功能限制;2、实现方法: C# web服务功能,不同机型使用不同接口进行数据获取,请求数据需要包含产品条码信息、请求方用户名信息; 接口请求如下: 3、部署注意事项: 在windows server IIS 管理器中添…

菜单权限的设计与实现

说明该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。说明:OverallAuth2.0 是一个简单、易懂、功能强大的权限+可视化流程管理系统。 友情提醒:本篇文章是属于系列文章,…

第十一章 成本管理(2025年详细解析版)

目录导语章节介绍什么是成本管理?关注两类成本11.1 管理基础项目成本管理的作用和意义项目成本失控原因(了解)成本类型机会成本沉没成本发展趋势和新兴实践如何计算进度偏差?11.2 项目成本管理过程过程概述项目成本管理过程裁剪时需要考虑的因素(不重要)在敏捷或适应型环…

寒假

今天继续学习Android Studio,今天学习的基础空间Button和EditText两个组件,了解了它们的属性,设计了一个简单的登录页面尝试获取前端的输入的信息,目前还未成功,经过学习,觉得融会贯通,目前认为,xml对应javaweb中的前端html页面,activity对应javaweb中的后端中的Contr…

操作系统课程设计:模拟进程调度

对 N 个进程应用模拟五种不同的进程调度算法,包括先来先服务(FCFS)、短进程优先(SJF)、时间片轮转(RR)、高响应比优先(HRRN)、动态优先级调度(PR)。2024年末《操作系统》课程设计大作业 模拟进程调度 对 N 个进程应用模拟五种不同的进程调度算法,包括先来先服务(F…