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$分, ...
随机推荐
- Gym 100801J Journey to the "The World's Start"(二分+单调队列)
题意: 现在有1,2,3...N这N个站, 给定限定时间Limt, N-1种票的价格, 分别对应一个最远距离, 叫你选择一种票, 满足可以在规定时间到达N站台,而且价格最低 思路: 如果买距离为L ...
- poj2420 A Star not a Tree? 模拟退火
题目大意: 给定n个点,求一个点,使其到这n个点的距离最小.(\(n \leq 100\)) 题解 模拟退火上 #include <cmath> #include <cstdio&g ...
- JS数组的sort排序
数组sort方法排序var aa=[6,2,1,5]//默认是从小到大排序aa.sort()[1, 2, 5, 6] //下面也是从小到大排序aa.sort(function(a,b){return ...
- HDU1247(经典字典树)
Hat’s Words Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入
<spring扩展点之二:spring中关于bean初始化.销毁等使用汇总,ApplicationContextAware将ApplicationContext注入> <spring ...
- css动画和渐变
变形: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 元素的变形:transform transform:none | <tra ...
- for循环及break和continue的区别
1.For循环 格式: for( 初始语句 ; 执行条件 ; 增量 ){ 循环体 } 执行顺序:1.初始语句 2.执行条件是否符合 3.循环体 4.增加增量 初始化语句只在循环开始前执行一次,每次 ...
- Qt弹出消息对话框
添加头文件 #include <QMessageBox> if(ui->lineEditXStart->text().isEmpty()) //判断lineedit输入内容是否 ...
- K.I.S.S 原则
KEEP IT SIMPLE, STUPID! 编写只做一件事情,并且要做好的程序:编写可以在一起工作的程序,编写处理文本流的程序,因为这是通用的接口.这就是UNIX哲学.所有的哲学真 正的浓缩为一个 ...
- Arcane Numbers 1
Vance and Shackler like playing games. One day, they are playing a game called "arcane numbers& ...