P3823_[NOI2017]蚯蚓排队 哈希+脑子
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$
观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$)。我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数,注意每次合并和分离时,只加入或删除与断开点距离小于等于$50$的;因为其他子串长度太长,或是已经在前几次中被添加在哈希表里了。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define ull unsigned long long
#define R register int
using namespace std;
namespace Fread {
//static char B[1<<15],*S=B,*D=B;
//#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
inline int g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
}
}using Fread::g;
const int N=,K=,mod=,M=,B=,S=;
int n,m,q,a[N],pre[N],nxt[N],cnt[N],s[(K<<)+];
ull t[S],p[K<<];
namespace HASH {
struct node { ull vl; int cnt,nxt; node(){}
node(ull v,int c,int n) {vl=v,cnt=c,nxt=n;}
}h[]; int fir[M],cnt=;
inline void add(ull x,int d) {
R st=x%M; for(R i=fir[st];i;i=h[i].nxt) if(h[i].vl==x){
h[i].cnt+=d; return ;
} h[++cnt]=node(x,d,fir[st]),fir[st]=cnt;
}
inline int query(ull x) {
R st=x%M; for(R i=fir[st];i;i=h[i].nxt)
if(h[i].vl==x) return h[i].cnt; return ;
}
inline void merge() {
R x=g(),y=g(); memset(s,,sizeof(s)); R l=K,r=l-;
for(R i=x;i&&l>;i=pre[i]) s[--l]=a[i];
for(R i=y;i&&r+<(K<<);i=nxt[i]) s[++r]=a[i];
for(R i=;i<=r;++i) t[i]=t[i-]*B+s[i];
for(R i=l;i<K;++i) for(R j=K;j<=r;++j) add(t[j]-t[i-]*p[j-i+],);
nxt[x]=y,pre[y]=x;
}
inline void div() {
R x=g(),y=nxt[x]; memset(s,,sizeof(s)); R l=K,r=l-;
for(R i=x;i&&l>;i=pre[i]) s[--l]=a[i];
for(R i=y;i&&r+<(K<<);i=nxt[i]) s[++r]=a[i];
for(R i=;i<=r;++i) t[i]=t[i-]*B+s[i];
for(R i=l;i<K;++i) for(R j=K;j<=r;++j) add(t[j]-t[i-]*p[j-i+],-);
nxt[x]=pre[y]=;
}
}
char str[];
inline ll query() { register ull vl=;
scanf("%s",str+); R k=g(),n=strlen(str+); register ll ans=;
if(k==) for(R i=;str[i];++i) ans=(ans*cnt[str[i]-''])%mod;
else { for(R i=;str[i];++i) t[i]=t[i-]*B+str[i]-'';
for(R i=k;str[i];++i) ans=(ans*HASH::query(t[i]-t[i-k]*p[k]))%mod;
} return ans;
}
signed main() {
#ifdef JACK
freopen("NOIPAK++.in","r",stdin);
#endif
n=g(),q=g(); p[]=; for(R i=;i<K;++i) p[i]=p[i-]*B;
for(R i=;i<=n;++i) a[i]=g(),++cnt[a[i]];
while(q--) {
R k=g(); if(k==) HASH::merge();
else if(k==) HASH::div();
else printf("%lld\n",query());
}
}
P3823_[NOI2017]蚯蚓排队 哈希+脑子的更多相关文章
- BZOJ4943 NOI2017蚯蚓排队(哈希+链表)
能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂 ...
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- 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值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
- [NOI2017]蚯蚓排队
嘟嘟嘟 现在看来这道题还不是特别难. 别一看到字符串就想SAM 看到\(k\)很小,所以我们可以搞一个单次修改复杂度跟\(k\)有关的算法. 能想到,每一次断开或链接,最多只会影响\(k ^ 2\)个 ...
- NOI2017蚯蚓排队
原题链接 发现 k<=50 ,在插入和删除时最多会影响不超过 k2 个串,用链表实现插入和删除,然后只需用哈希表维护每个长度不超过k的串的出现次数,哈希的话可以先用比较大的范围的值处理冲突,再映 ...
- bzoj4943 [Noi2017]蚯蚓排队
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分, ...
随机推荐
- 每天一个linux命令(6):rm命令
版权声明更新:2017-05-10博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1文章介绍 本文介绍了Linux下面的rm命令. 2 开 ...
- [Luogu3960][NOIP2017]列队
luogu sol 震惊!\(NOIP\)居然也出数据结构! 话说回来,其实只需要对每一行的前\(m-1\)个人维护一个数据结构,然后对最后一列的\(m\)个人也维护一个数据结构就好了.具体的话写平衡 ...
- 问题7:如何实现用户的历史记录功能(最多n条)
实例:制作猜字游戏,添加历史记录功能,显示用户最近猜过的数字 解决方案:使用容量为n的队列存储历史记录 使用标准库colections中的deque,一个双端循环队列 程序退出前,可以使用pickle ...
- java对象在内存中的结构(HotSpot虚拟机)
一.对象的内存布局 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 从上面的这张图里面可以 ...
- Java 的 Tuple 元组数据类型
元组类型,即 Tuple 常在脚本语言中出现,例如 Scala 的 ("Unmi", "china@qq.com", "blahbla"). ...
- 【转载】ruby 中数组函数示例(1)(转)
函数名称 说明 示例 & 数组与,返回两数组的交集 [1,2] & [2,3] =>[2] * 复制数组n次 [1,2]*2 => [1,2,1, ...
- ES6学习之Promise
详见之前文章:Promise详解
- VC6.0 工程转到VS2010一些问题的描述及解决方法
下列为VC6.0 工程转到VS2008一些问题的描述及解决方法 //////////////////////////////////////////////////////////////////// ...
- AlteraFPGA使用通用SPIFlash - 张亚群的技术专栏 - 博客频道 - CSDN.NET
AlteraFPGA使用通用SPIFlash - 张亚群的技术专栏 - 博客频道 - CSDN.NET Altera器件有EPCS系列配置器件,其实,这些配置器件就是我们平时通用的SPIFlash,据 ...
- 多对多 hibernate映射
数据库: create table EMPLOYEE ( EMPID NUMBER(6) not null, EMPNAME VARCHAR2(32) ) alter table EMPLOYEE a ...