之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$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]蚯蚓排队 哈希+脑子的更多相关文章

  1. BZOJ4943 NOI2017蚯蚓排队(哈希+链表)

    能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂 ...

  2. 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】

    题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...

  3. BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...

  4. 【uoj#315/bzoj4943】[NOI2017]蚯蚓排队 Hash

    题目描述 给出 $n$ 个字符,初始每个字符单独成字符串.支持 $m$ 次操作,每次为一下三种之一: $1\ i\ j$ :将以 $i$ 结尾的串和以 $j$ 开头的串连到一起. $2\ i$ :将 ...

  5. [NOI2017]蚯蚓排队 hash

    题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...

  6. 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】

    题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...

  7. [NOI2017]蚯蚓排队

    嘟嘟嘟 现在看来这道题还不是特别难. 别一看到字符串就想SAM 看到\(k\)很小,所以我们可以搞一个单次修改复杂度跟\(k\)有关的算法. 能想到,每一次断开或链接,最多只会影响\(k ^ 2\)个 ...

  8. NOI2017蚯蚓排队

    原题链接 发现 k<=50 ,在插入和删除时最多会影响不超过 k2 个串,用链表实现插入和删除,然后只需用哈希表维护每个长度不超过k的串的出现次数,哈希的话可以先用比较大的范围的值处理冲突,再映 ...

  9. bzoj4943 [Noi2017]蚯蚓排队

    题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分, ...

随机推荐

  1. S3C2410中文芯片手册-11.串口

    目录 11 UART Overview Featrues UART Operation Data Transmission Data Reception Auto Flow Control(AFC) ...

  2. Dubbo注册中心的四种配置方式详解

    Dubbo目前支持4种注册中心,(multicast,zookeeper,redis,simple) 推荐使用Zookeeper注册中心. 一.Multicast注册中心 不需要启动任何中心节点,只要 ...

  3. js一个游戏小笔记

    昨天写了个飞机大战的游戏,没弄好的一点是如何移动炮台. 开始我把移动代码写到了炮台类里面,但是怎么按都不移动.(最烦,代码对,效果不对,╮(╯▽╰)╭) 问过老师才知道,这种移动类游戏,应该把  控制 ...

  4. JavaScript-Tool:pluload

    ylbtech-JavaScript-Tool:pluload Plupload是用于处理文件上传的JavaScript API,支持多文件选择.文件类型过滤.请求分块.客户端图像缩放等功能,使用不同 ...

  5. JavaScript-Tool:jquery.cxselect.js

    ylbtech-JavaScript-Tool:jquery.cxselect.js 1.返回顶部 1.jquery.cxselect.js /*! * jQuery cxSelect * @name ...

  6. c++17 filesystem, regex 遍历目录

    linux 遍历目录+文件(优化版本) c++17 FS 还是挺好用的, VS2017支持,但是linux g++7.3 还是不支持 filesystem #include<filesystem ...

  7. Ruby中的%表示法

     %{String}  用于创建一个使用双引号括起来的字符串,这个表示法与%Q{String}完全一样 result = %{hello} puts "result is: #{result ...

  8. mybatis---demo1--(1-n)----bai

    实体类1: package com.etc.entity; import java.util.List; public class Teacher { private int tid; private ...

  9. [原创] 新人分享--ORA-01012:not logged on的解决办法 [复制链接]

    转自:http://f.dataguru.cn/thread-82530-1-1.html

  10. Ajax效果--个人收藏

    $.ajax({ url: "../../../Tools/WeChatMenu.ashx?action=get_menu", type: "post", da ...