[NOI2017]蚯蚓排队(链表+hash)
这题看题面感觉挺玄学的,但其实会挂链式hash就能暴力切了,就是纸老虎,考察选手的语文水平。不过三年没写挂链hash也应该写一下了……
首先模数设成自然溢出ull,然后挂链时的模数取2^24。然后就可以直接hash了。对于3操作直接O(Σ|S|)询问即可,对于1、2操作,直接暴力加、减长度不超过50的字符,毕竟k<=50,这是个关键性条件。所以暴力能切了。
下面分析时间复杂度:先假设没有2操作,因为每一个位置只有长度不超过50的,每次加的数量也是不超过50的,这样总复杂度是均摊O(nk)的;再考虑2操作,因为2操作数量很少,而且每次只会至多影响O(k2)个数,因此考虑2操作后,复杂度是O(ck2)的,于是总复杂度是O(nk+ck2+Σ|S|)。注意hash不能用map,要挂链,因为map自带大常数和log,为什么不能unordered_map呢?因为这是NOI,不能用c++11。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=5e5+,p=,mod=,gloid=(<<)-;
int n,m,q,a[N],pre[N],nxt[N],cnt[N],f[];
ull h[],pw[];
char s[];
struct Hash{
struct edge{ull x;int v,nxt;}e[];
int hd[gloid+],ecnt;
void add(ull x,int d)
{
int u=x&gloid;
for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x){e[i].v+=d;return;}
e[++ecnt]=(edge){x,d,hd[u]},hd[u]=ecnt;
}
int query(ull x)
{
int u=x&gloid;
for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x)return e[i].v;
return ;
}
}mp;
void merge()
{
int x,y,L=,R=;scanf("%d%d",&x,&y);
memset(f,,sizeof f);
for(int i=x;i&&L>;i=pre[i])f[--L]=a[i];
for(int i=y;i&&R<;i=nxt[i])f[++R]=a[i];
for(int i=;i<=R;i++)h[i]=h[i-]*p+f[i];
for(int i=L;i<=;i++)
for(int j=;j<=min(R,i+);j++)
mp.add(h[j]-h[i-]*pw[j-i+],);
nxt[x]=y,pre[y]=x;
}
void split()
{
int x,y,L=,R=;scanf("%d",&x),y=nxt[x];
memset(f,,sizeof f);
for(int i=x;i&&L>;i=pre[i])f[--L]=a[i];
for(int i=y;i&&R<;i=nxt[i])f[++R]=a[i];
for(int i=;i<=R;i++)h[i]=h[i-]*p+f[i];
for(int i=L;i<=;i++)
for(int j=;j<=min(R,i+);j++)
mp.add(h[j]-h[i-]*pw[j-i+],-);
nxt[x]=pre[y]=;
}
int query()
{
scanf("%s",s+);
int len=strlen(s+),ret=,k;
scanf("%d",&k);
ull val=;
if(k==)
{
for(int i=;i<=len;i++)ret=1ll*ret*cnt[s[i]]%mod;
return ret;
}
for(int i=;i<=len;i++)
{
val=val*p+s[i];
if(i>k)val-=pw[k]*s[i-k];
if(i>=k)ret=1ll*ret*mp.query(val)%mod;
}
return ret;
}
int main()
{
scanf("%d%d",&n,&q);
pw[]=;for(int i=;i<=;i++)pw[i]=pw[i-]*p;
for(int i=;i<=n;i++)scanf("%d",&a[i]),a[i]+='',cnt[a[i]]++;
while(q--)
{
int op;scanf("%d",&op);
if(op==)merge();
else if(op==)split();
else printf("%d\n",query());
}
}
[NOI2017]蚯蚓排队(链表+hash)的更多相关文章
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
- BZOJ4943 NOI2017蚯蚓排队(哈希+链表)
能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂 ...
- [NOI2017]蚯蚓排队 hash
题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...
- 【uoj#315/bzoj4943】[NOI2017]蚯蚓排队 Hash
题目描述 给出 $n$ 个字符,初始每个字符单独成字符串.支持 $m$ 次操作,每次为一下三种之一: $1\ i\ j$ :将以 $i$ 结尾的串和以 $j$ 开头的串连到一起. $2\ i$ :将 ...
- LOJ 2303 「NOI2017」蚯蚓排队——链表+哈希表
题目:https://loj.ac/problem/2303 想到合并的时候可以只考虑接口附近的50个,但不太会分析复杂度,而且没有清楚地想到用哈希值对应个数. 看了题解才会…… 一直想用 splay ...
- BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
- bzoj4943 [Noi2017]蚯蚓排队
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分, ...
- [NOI2017]蚯蚓排队
嘟嘟嘟 现在看来这道题还不是特别难. 别一看到字符串就想SAM 看到\(k\)很小,所以我们可以搞一个单次修改复杂度跟\(k\)有关的算法. 能想到,每一次断开或链接,最多只会影响\(k ^ 2\)个 ...
- P3823_[NOI2017]蚯蚓排队 哈希+脑子
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...
随机推荐
- 微信小程序实现左滑删除效果(原生/uni-app)
实现效果 列表中侧滑删除 删除不同时存在 scrollview上下滑动与侧滑删除不影响 uni-app实现 html部分 <template> <scroll-view :scrol ...
- 51nod 1055:最长等差数列
1055 最长等差数列 基准时间限制:2 秒 空间限制:262144 KB 分值: 80 难度:5级算法题 收藏 取消关注 N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 ...
- netty权威指南学习笔记一——NIO入门(4)AIO
NIO2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现.异步通道提供以下两种方式获取操作结果. 1.通过java.util.concurrent.Future 类来表示异步操 ...
- doc转docx
# -*- coding: utf-8-*- import win32com from win32com.client import Dispatch w = win32com.client.Disp ...
- [洛谷Luogu]P1141 01迷宫[联通块 并查集]
题目链接 大致题意 相邻格子不同为连通,计算每个点所在的连通块大小. 想法 我采用了并查集的做法. 开一个辅助数组记录连通块大小,每次合并的时候更新父亲节点的大小即可. 一个点先与它上面的点判定,若判 ...
- 面试题(10)之 leetcode-26
题目描述 解法一 对数组去重求数组长度,没有必要 /** * @param {number[]} nums * @return {number} */ var removeDuplicates = f ...
- JAVA的控制结构
一.控制结构 1.控制结构概述 控制结构是控制程序如何运行的特殊的语句结构.控制结构可以分为:顺序控制结构,分支控制结构和循环控制结构. 2.顺序控制结构 除了分支控制结构和循环控制结构之外的语句都是 ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-map-marker
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- vue学习(八)nextTick[异步更新队列]的使用和应用
nextTick的使用 为了数据变化之后等待vue完成更新DOM,可以在数据变化之后立即使用Vue.nextTick()在当前的回调函数中能获取最新的DOM <div id="app& ...
- IT日常技能:VMware网络配置
1.0 基本概念 集线器:把一流量为M的端口分为N个端口,每个端口流量为M/N 交换机:把一流量为M的端口分为N个端口,每个端口流量仍为M 路由器:相当于两块网卡,一块连接外网并负责NAT, 另一块负 ...