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$分, ...
随机推荐
- bzoj 4199: [Noi2015]品酒大会 后缀树
题目大意: 给定一个长为n的字符串,每个下标有一个权\(w_i\),定义下标\(i,j\)是r相似的仅当\(r \leq LCP(suf(i),suf(j))\)且这个相似的权为\(w_i,w_j\) ...
- bzoj 2716 天使玩偶 —— K-D树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2716 果然和 bzoj 2648 是一样的吧: 只是数组要迷之开大,3e5+5 会RE? 代 ...
- poj 1273 Drainage Ditches(最大流,E-K算法)
一.Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clove ...
- VisualGDB系列1:VisualGDB总体概述
根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文总体介绍VisualGDB能给你带来 ...
- Python函数(十二)-迭代器
字符串,列表,元组,字典,集合,生成器这些能通过for循环来遍历的数据类型都是可迭代对象 可通过isinstance判断是不是可迭代对象 >>> from collections i ...
- excel2003, 2007最大行列、sheet数
1.excel2003版本一个工作表最多可有65536行,行用数字1—65536表示; 256列,列用英文字母A—Z,AA—AZ,BA—BZ,……,IA—IV表示.2.一个工作簿中最多含有25 ...
- [cf687c]The Values You Can Make(01背包变形)
题意:给定n个硬币,每个硬币都有面值,求每个能构成和为k的硬币组合中,任意个数相互求和的总额种类,然后将所有硬币组合中最后得到的结果输出. 解题关键:在01背包的过程中进行dp.dp[i][j]表示组 ...
- 1、转载 bwa的使用方法
http://bio-bwa.sourceforge.net/bwa.shtml http://www.plob.org/?p=25 bwa的使用需要两中输入文件: Reference genome ...
- Spring入门第五课
集合属性 在Spring中可以通过一组内置的xml标签(如:<list>,<set>,<map>)来配置集合属性. 配置java.util.List类型的属性,需要 ...
- 一款Regular expression在线检测工具
记录下我自己使用的一款正则表达式使用工具 https://regex101.com/ 输入正则表达式后,可以在下面的“TEST STRING”中来测试对应的字符串是否满足该正则表达式 个人觉得非常好用