BZOJ4943 [NOI2017] 蚯蚓
题目描述
蚯蚓幼儿园有nn 只蚯蚓。幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演。
所有蚯蚓用从11 到nn 的连续正整数编号。每只蚯蚓的长度可以用一个正整数表示,根据入园要求,所有蚯蚓的长度都不超过66 。神刀手希望这些蚯蚓排成若干个队伍,初始时,每只蚯蚓各自排成一个仅有一只蚯蚓的队伍,该蚯蚓既在队首,也在队尾。
神刀手将会依次进行mm 次操作,每个操作都是以下三种操作中的一种:
给出ii 和jj ,令ii 号蚯蚓与jj 号蚯蚓所在的两个队伍合并为一个队伍,具体来说,令jj 号蚯蚓紧挨在ii 号蚯蚓之后,其余蚯蚓保持队伍的前后关系不变。
给出ii ,令ii 号蚯蚓与紧挨其后的一只蚯蚓分离为两个队伍,具体来说,在分离之后,ii 号蚯蚓在其中一个队伍的队尾,原本紧挨其后的那一只蚯蚓在另一个队伍的队首,其余蚯蚓保持队伍的前后关系不变。
- 给出一个正整数kk 和一个长度至少为kk 的数字串ss ,对于ss 的每个长度为kk 的连续子串tt (这样的子串共有|s| - k + 1∣s∣−k+1 个,其中|s|∣s∣ 为ss 的长度),定义函数f(t)f(t) ,询问所有这些f(t)f(t) 的乘积对998244353998244353 取模后的结果。其中f(t)f(t) 的定义如下: 对于当前的蚯蚓队伍,定义某个蚯蚓的向后kk 数字串为:从该蚯蚓出发,沿队伍的向后方向,寻找最近的kk 只蚯蚓(包括其自身),将这些蚯蚓的长度视作字符连接而成的数字串;如果这样找到的蚯蚓不足kk只,则其没有向后kk 数字串。例如蚯蚓的队伍为1010 号蚯蚓在队首,其后是2222 号蚯蚓,其后是33 号蚯蚓(为队尾),这些蚯蚓的长度分别为44 、55 、66 ,则1010 号蚯蚓的向后33 数字串 为456,2222 号蚯蚓没有向后33 数字串,但其向后22 数字串为56,其向后11 数字串为5。
而f(t)f(t) 表示所有蚯蚓中,向后kk 数字串恰好为tt 的蚯蚓只数。
输入输出格式
输入格式:
输入文件的第一行有两个正整数n,mn,m ,分别表示蚯蚓的只数与操作次数。
第二行包含nn 个不超过66 的正整数,依次表示编号为1, 2, \dots , n1,2,…,n 的蚯蚓的长度。
接下来mm 行,每行表示一个操作。每个操作的格式可以为:
1 i j
(1 \leqslant i, j \leqslant n)(1⩽i,j⩽n) 表示:令ii 号与jj 号蚯蚓所在的两个队伍合并为一个队伍,新队伍中,jj 号蚯蚓紧挨在ii 号蚯蚓之后。保证在此操作之前,ii 号蚯蚓在某个队伍的队尾,jj 号蚯蚓在某个队伍的队首,且两只蚯蚓不在同一个队伍中。2 i
(1 \leqslant i \leqslant n)(1⩽i⩽n) 表示:令ii 号蚯蚓与紧挨其后一个蚯蚓分离为两个队伍。保证在此操作之前,ii 号蚯蚓不是某个队伍的队尾。3 s k
(kk 为正整数,ss 为一个长度至少为kk 的数字串)表示:询问ss 的每个长度为kk 的子串tt 的f(t)f(t) 的乘积,对998244353998244353 取模的结果。f(t)f(t) 的定义见题目描述。
同一行输入的相邻两个元素之间,用恰好一个空格隔开。
输入文件可能较大,请不要使用过于缓慢的读入方式。
输出格式:
依次对于每个形如3 s k
的操作,输出一行,仅包含一个整数,表示询问的结果。
题目大意:
一个初始全为单个元素的集合,支持合并,分裂,查询s,k求出s所有长度为k的子串在现有的序列中出现的次数的乘积。
题解:
①用链表记录nxt[],pre[]来模拟分裂,合并;
②考虑到k<=50,意思就是我们只需要维护长度在50以内串,外加查询其出现的次数。而分裂操作c并不多,意味着合并也并不多。暴力维护即可:每次合并分裂时枚举跨过断点前后50位以内的串修改。
③用hash散列表来修改和查询,由于hash的模值比较大,无法开下所有v值,就可以将v类似于存边存进v%sz里,每次修改和查询暴力枚举一遍,复杂度几乎为O(1)
#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 200010
#define M 11000000
#define base 1000000007
#define mod 998244353
#define ull unsigned long long
using namespace std;
int n,m,pre[N],nxt[N];
char tmp[M],*P = tmp,*s,a[N];
ull H[M],pw[M];
char gc(){
static char *p1,*p2,s[];
if(p1==p2) p2=(p1=s)+fread(s,,,stdin);
return(p1==p2)?EOF:*p1++;
}
int rd(){
int x = ,f = ; char c = gc();
while(c<''||c>'') {if(c=='-') f = -; c = gc();}
while(c>=''&&c<='') {x = x * + c - ''; c = gc();}
return x * f;
}
int rd(char *c){
char *st = c;
do *c = gc(); while(*c<''||*c>'');
do *++c = gc(); while(*c>=''&&*c<='');
*c = ;
return c - st;
}
struct Edge{ull v; int nt,w;};
const int sz = 1e7;
struct HASH{
Edge E[sz + ]; int o,hd[sz + ];
int& adde(ull v){
E[++o] = (Edge){v,hd[v%sz],}; hd[v%sz] = o;
return E[o].w;
}
int& operator [] (ull v){
for(int i = hd[v%sz];i;i=E[i].nt)
if(E[i].v==v) return E[i].w;
return adde(v);
}
int val(ull v){
for(int i = hd[v%sz];i;i=E[i].nt)
if(E[i].v==v) return E[i].w;
return ;
}
}Hash;
void cal(int y,int x){
static char S[N]; int len = ,fg;
int st;for(st = y;pre[st]&&len<=;st = pre[st],len++); fg = ++len;
int ed;for(ed = y;nxt[ed]&&len<=;ed = nxt[ed],len++);
len = ; //S[++len] = a[st];
for(int i = st;nxt[i];i = nxt[i]) S[++len] = a[i];
S[++len] = a[ed];
for(int i = ;i <= len;i++) H[i] = H[i - ]*base + S[i];
for(int i = fg;i <= len;i++)
for(int j = max(i - ,);j < fg - ;j++){
Hash[H[i] - H[j] * pw[i - j]]+=x;
}
}
int main()
{ //freopen("mzoj1112.in","r",stdin);
//freopen("mzoj1112.out","w",stdout);
n = rd(); m = rd();
for(int i = pw[] = ;i < M;i++) pw[i] = pw[i - ] * base;
for(int i = ;i <= n;i++) Hash[a[i] = rd() + '']++;
for(int i = ,typ,x,y,len,k;i <= m;i++){
typ = rd();
if(typ==) {
x = rd(); y = rd();
pre[y] = x; nxt[x] = y;
cal(y,);
}
else if(typ==){
x = rd(); y = nxt[x];
cal(y,-);
pre[y] = nxt[x] = ;
}
else{
s = P; len = rd(s+); P += len + ; k = rd();
ull ans = ;
for(int i = ;i <= len;i++){
H[i] = H[i - ]*base + s[i];
if(i>=k) {
ull temp = H[i] - H[i - k] * pw[k];
ans = ans * Hash.val(temp) % mod;
}
}
printf("%llu\n",ans);
}
}
return ;
}//by tkys_Austin;
BZOJ4943 [NOI2017] 蚯蚓的更多相关文章
- [Bzoj4943][Noi2017]蚯蚓(hash)
4943: [Noi2017]蚯蚓 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 237 Solved: 110[Submit][Status][D ...
- BZOJ4943 NOI2017蚯蚓排队(哈希+链表)
能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂 ...
- bzoj4943 [Noi2017]蚯蚓排队
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分, ...
- BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
- 【uoj#315/bzoj4943】[NOI2017]蚯蚓排队 Hash
题目描述 给出 $n$ 个字符,初始每个字符单独成字符串.支持 $m$ 次操作,每次为一下三种之一: $1\ i\ j$ :将以 $i$ 结尾的串和以 $j$ 开头的串连到一起. $2\ i$ :将 ...
- [NOI2017]蚯蚓排队 hash
题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- P3823_[NOI2017]蚯蚓排队 哈希+脑子
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
随机推荐
- 201621123043 《Java程序设计》第3周学习总结
1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系.步骤如下: 1.1 写出你 ...
- 几款有用的AndroidStudio插件
1.Android Parcelable code generator 顾名思义,这是个生成实现了Parcelable接口的代码的插件. 在你的类中,按下alt + insert键弹出插入代码的上下文 ...
- linux服务器操作系统,在相同环境下,哪个做lamp服务器更稳定点?哪个版本更稳定?
随着国内WEB服务越来越多,如何才能选择一个合适的linux服务器操作系统?在国内用的最多的好像是红帽子系列也就是red hat系列,但有些版本缺乏稳定性.新手在选择操作系统的时候最好只用偶数版本,还 ...
- 深入浅出 SSL 管理配置实战
我们生活在一个信息大爆炸的时代,几乎每天都在和互联网打交道,购物.网银转账.支付宝付款.搜索信息.查看邮件.观看视频.微信聊天.上网冲浪.阅读新闻等,无不时时刻刻在和网络打交道.那如何保护网络安全就相 ...
- 如何用UPA优化性能?先读懂这份报告!
一.概述 打开一份UPA报告时,最先看到的就是概述页面,这也是我们推荐用户第一时间关注的页面.概述页面一开始会列出测试的基本信息,并根据腾讯游戏的性能标准,给出本次测试的结果(通过,不通过和警告): ...
- python中 return 的用法
return 语句就是讲结果返回到调用的地方,并把程序的控制权一起返回 程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return. 要返回两个数值,写成一行即可: de ...
- 《深入实践Spring Boot》阅读笔记之二:分布式应用开发
上篇文章总结了<深入实践Spring Boot>的第一部分,这篇文章介绍第二部分:分布式应用开发,以及怎么构建一个高性能的服务平台. 主要从以下几个方面总结: Spring Boot SS ...
- spring-oauth-server实践:授权方式四:client_credentials 模式下有效期内重复申请 access_token ?
spring-oauth-server入门(1-12)授权方式四:client_credentials 模式下有效期内重复申请 access_token ? 一.失效重建邏輯 二.如果沒有失效,不会重 ...
- java 中String类的常用方法总结,带你玩转String类。
String类: String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.String类对象创建后不能修改,StringBuffer & St ...
- FreeMarker的用法
freemark就是一个对静态页面上的标签进行动态解析.填充数据的一个框架. 语法(转:http://zhuyuehua.iteye.com/blog/1975251): 1. freemarker ...