BZOJ4943 NOI2017蚯蚓排队(哈希+链表)
能看懂题就能想到正解。维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况。由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂度为O(Σ|s|)。于是总复杂度为O(nk+ck^2+Σ|s|)。
手写哈希注意插入元素时考虑清楚,如果没有哈希冲突不需要更新哈希使用的链表,所以特判一下。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=;char c=getchar();
while (c<''||c>'') c=getchar();
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x;
}
#define N 200010
#define S 10000010
#define K 50
#define P 19260817
#define MOD 998244353
#define G 7
#define ul unsigned long long
int n,m,POW[K+][];
struct data{int x,pre,nxt;
}a[N];
int ch[S];
int map[P+],cnt[P+],nxt[P+];
ul value[P+],POWv[K+][];
void ins(int x,ul v)
{
if (!map[x]) map[x]=,value[x]=v,cnt[x]=;
else
{
int t;
while (map[x]&&value[x]!=v) t=x,x=nxt[x];
if (map[x]) cnt[x]++;
else map[x]=,value[x]=v,cnt[x]=,nxt[t]=x;
}
}
void del(int x,ul v)
{
while (value[x]!=v) x=nxt[x];
cnt[x]--;
}
int query(int x,ul v)
{
while (map[x]&&value[x]!=v) x=nxt[x];
return cnt[x];
}
int main()
{
n=read(),m=read();
for (int i=;i<P-;i++) nxt[i]=i+;nxt[P-]=;
for (int j=;j<=;j++)
{
POW[][j]=j;for (int i=;i<=K;i++) POW[i][j]=POW[i-][j]*G%P;
POWv[][j]=j;for (int i=;i<=K;i++) POWv[i][j]=POWv[i-][j]*G;
}
for (int i=;i<=n;i++) a[i].x=read(),ins(a[i].x,a[i].x);
while (m--)
{
int op=read();
switch(op)
{
case :
{
int x=read(),y=read();
a[x].nxt=y,a[y].pre=x;
for (int l=,h=x;h&&l<K;h=a[h].pre,l++)
{
int hash=;ul hashv=;
for (int i=,t=h;i<=l;t=a[t].nxt,i++)
hash=(hash*G+a[t].x)%P,hashv=hashv*G+a[t].x;
for (int i=l+,t=y;t&&i<=K;t=a[t].nxt,i++)
{
hash=(hash*G+a[t].x)%P,hashv=hashv*G+a[t].x;
ins(hash,hashv);
}
}
break;
}
case :
{
int x=read(),y=a[x].nxt;
for (int l=,h=x;h&&l<K;h=a[h].pre,l++)
{
int hash=;ul hashv=;
for (int i=,t=h;i<=l;t=a[t].nxt,i++)
hash=(hash*G+a[t].x)%P,hashv=hashv*G+a[t].x;
for (int i=l+,t=y;t&&i<=K;t=a[t].nxt,i++)
{
hash=(hash*G+a[t].x)%P,hashv=hashv*G+a[t].x;
del(hash,hashv);
}
}
a[x].nxt=;a[y].pre=;
break;
}
case :
{
char c=getchar();int l=;
while (c<''||c>'') c=getchar();
while (c>=''&&c<='') ch[++l]=c^,c=getchar();
int k=read();
int hash=;ul hashv=;
for (int i=;i<k;i++)
hash=(hash*G+ch[i])%P,hashv=hashv*G+ch[i];
int ans=;
for (int i=k;i<=l;i++)
{
hash=(hash*G+ch[i]-POW[k][ch[i-k]]+P)%P,
hashv=hashv*G+ch[i]-POWv[k][ch[i-k]];
ans=1ll*ans*query(hash,hashv)%MOD;
}
printf("%d\n",ans);
}
}
}
return ;
}
BZOJ4943 NOI2017蚯蚓排队(哈希+链表)的更多相关文章
- bzoj4943 [Noi2017]蚯蚓排队
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分, ...
- P3823_[NOI2017]蚯蚓排队 哈希+脑子
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...
- [Bzoj4943][Noi2017]蚯蚓(hash)
4943: [Noi2017]蚯蚓 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 237 Solved: 110[Submit][Status][D ...
- BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- 【uoj#315/bzoj4943】[NOI2017]蚯蚓排队 Hash
题目描述 给出 $n$ 个字符,初始每个字符单独成字符串.支持 $m$ 次操作,每次为一下三种之一: $1\ i\ j$ :将以 $i$ 结尾的串和以 $j$ 开头的串连到一起. $2\ i$ :将 ...
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
- [NOI2017]蚯蚓排队(链表+hash)
这题看题面感觉挺玄学的,但其实会挂链式hash就能暴力切了,就是纸老虎,考察选手的语文水平.不过三年没写挂链hash也应该写一下了…… 首先模数设成自然溢出ull,然后挂链时的模数取2^24.然后就可 ...
- BZOJ4943 [NOI2017] 蚯蚓
题目描述 蚯蚓幼儿园有nn 只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从11 到nn 的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示,根据入园要求,所有蚯蚓的长 ...
随机推荐
- C语言程序设计II—第六周教学
第六周教学总结(1/4-7/4) 教学内容 本周的教学内容为:第八章 指针 8.1 密码开锁(知识点:指针和指针变量的概念),8.2 角色互换(知识点:指针作为函数的参数返回多个值) 重点.难点:指针 ...
- Linux系列教程(六)——Linux常用命令之文件搜索命令
前一篇博客我们讲解了Linux链接命令和权限管理命令, 通过 ln -s 链接名 表示创建软链接,不加-s表示创建硬链接:还有三个更改权限的命令,chmod命令可以更改文件或目录权限,chown命令 ...
- 一个简单的javascript节流器实现
节流器 javascript的节流器主要用于延缓某些动作的执行,比如ajax请求,如果input框注册了input事件,那么当用户输入时就会持续的触发这个事件,如果回调函数中持续的通过ajax调用后台 ...
- Luogu4249 WC2007 石头剪刀布 费用流
传送门 考虑竞赛图三元环计数,设第\(i\)个点的入度为\(d_i\),根据容斥,答案为\(C_n^3 - \sum C_{d_i}^2\) 所以我们需要最小化\(\sum C_{d_i}^2\) 考 ...
- React-使用styled-components
1.安装 npm install --save styled-components 2.简单使用 style.js: import styled from 'styled-components'; i ...
- RHEL7VIM编辑器
本文介绍Vim编辑器的使用 vi和vim的区别 它们都是多模式编辑器 不同的是vim是vi的升级版本 它不仅兼容vi的所有指令而且还有一些新的特性在里面 vim的这些优势主要体现在以下几个方面 多级撤 ...
- SAAS云平台搭建札记: (一) 浅论SAAS多租户自助云服务平台的产品、服务和订单
最近在做一个多租户的云SAAS软件自助服务平台,途中遇到很多问题,我会将一些心得.体会逐渐分享出来,和大家一起探讨.这是本系列的第一篇文章. 大家知道,要做一个全自助服务的SAAS云平台是比较复杂的, ...
- HNOI2019 多边形 polygon
HNOI2019 多边形 polygon https://www.luogu.org/problemnew/show/P5288 这题镪啊... 首先堆结论: 显然终止状态一定是所有边都连向n了 根据 ...
- 如何使用串口来给STM32下载程序
前言 第一次学习STM32的时候,不知道有调试器这个东西,所以一直是通过串口来给STM32下载程序,下载速度也还算可以,一般是几秒钟完成.后来用了调试器,可以直接在Keil环境下进行下载,而且还可以进 ...
- 大数据之Flume
什么是Flume ApacheFlume是一个分布式的.可靠的.可用的系统,用于高效地收集.聚合和将大量来自不同来源的日志数据移动到一个集中的数据存储区. 系统要求 1. JDK 1.8 或以上版本 ...