bzoj4943 [Noi2017]蚯蚓排队
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf
正解:字符串$hash$。
我在考场上写了个$map$的$hash$被卡成$40$分,然后改成挂链版本的就$AC$了。。$mdzz$,以后$hash$再也不写$map$了。。
我们考虑使用链表来表示字符间的关系,合并和分裂都用链表来表示,这样我们可以快速找到两个字符的前$k$个和后$k$个字符。
注意到每次只会增加或减少$k^{2}$个字符串,那么我们直接把这些字符串$hash$起来即可,查询统计也很简单。
这道题好像是被骂得最惨的一道题??有人说出题人想告诉我们$SAM$,后缀数组这些高级字符串数据结构都没用。。
//It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define rhl (998244353)
#define wyh (19260817)
#define M (10000010)
#define N (300010)
#define il inline
#define RG register
#define ll long long
#define ull unsigned long long using namespace std; struct edge{ int nt,sum; ull v; }g[]; int head[wyh+],a[N],lst[N],nxt[N],st1[],st2[],tong[],n,m,num,fg,top1,top2;
ull hsh[M],bin[M],base=;
char s[M];
ll ans; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void insert(RG int from,RG ull to){
g[++num]=(edge){head[from],,to},head[from]=num; return;
} il void add(RG ull Hash){
RG int ymd=Hash%wyh;
for (RG int i=head[ymd];i;i=g[i].nt)
if (g[i].v==Hash){ ++g[i].sum; return; }
return insert(ymd,Hash);
} il void del(RG ull Hash){
RG int ymd=Hash%wyh;
for (RG int i=head[ymd];i;i=g[i].nt)
if (g[i].v==Hash){ --g[i].sum; return; }
return;
} il ll calc(RG ull Hash){
RG int ymd=Hash%wyh;
for (RG int i=head[ymd];i;i=g[i].nt)
if (g[i].v==Hash) return g[i].sum;
return ;
} int main(){
#ifndef ONLINE_JUDGE
freopen("queue.in","r",stdin);
freopen("queue.out","w",stdout);
#endif
n=gi(),m=gi(),fg=,bin[]=;
for (RG int i=;i<=;++i) bin[i]=bin[i-]*base;
for (RG int i=;i<=n;++i){ a[i]=gi(),++tong[a[i]]; if (a[i]!=) fg=; }
for (RG int i=;i<=n;++i) lst[i]=nxt[i]=i;
for (RG int p=,op,x,y,k,len;p<=m;++p){
op=gi();
if (op==){
x=gi(),y=gi(),top1=top2=,st1[++top1]=x,st2[++top2]=y;
for (RG int i=x;top1< && lst[i]!=i;i=lst[i]) st1[++top1]=lst[i];
for (RG int i=y;top2< && nxt[i]!=i;i=nxt[i]) st2[++top2]=nxt[i];
RG ull Hsh=; for (RG int i=top1;i;--i) Hsh=Hsh*base+a[st1[i]]; st1[top1+]=;
for (RG int i=top1;i;--i){
RG ull Hash=Hsh-a[st1[i+]]*bin[i]; Hsh=Hash,len=i;
for (RG int j=;j<=top2;++j){
++len; if (len>) break;
Hash=Hash*base+a[st2[j]],add(Hash);
}
}
nxt[x]=y,lst[y]=x;
}
if (op==){
x=gi(),y=nxt[x],top1=top2=,st1[++top1]=x,st2[++top2]=y;
for (RG int i=x;top1< && lst[i]!=i;i=lst[i]) st1[++top1]=lst[i];
for (RG int i=y;top2< && nxt[i]!=i;i=nxt[i]) st2[++top2]=nxt[i];
RG ull Hsh=; for (RG int i=top1;i;--i) Hsh=Hsh*base+a[st1[i]]; st1[top1+]=;
for (RG int i=top1;i;--i){
RG ull Hash=Hsh-a[st1[i+]]*bin[i]; Hsh=Hash,len=i;
for (RG int j=;j<=top2;++j){
++len; if (len>) break;
Hash=Hash*base+a[st2[j]],del(Hash);
}
}
nxt[x]=x,lst[y]=y;
}
if (op==){
scanf("%s",s+),k=gi(),len=strlen(s+),ans=; RG ull Hash;
if (k==){
for (RG int i=;i<=len;++i) ans=ans*(ll)tong[s[i]-]%rhl;
printf("%lld\n",ans); continue;
}
for (RG int i=;i<=len;++i) hsh[i]=hsh[i-]*base+s[i]-;
for (RG int i=;i+k-<=len;++i){
Hash=hsh[i+k-]-hsh[i-]*bin[k];
ans=ans*calc(Hash)%rhl;
}
printf("%lld\n",ans);
}
}
return ;
}
bzoj4943 [Noi2017]蚯蚓排队的更多相关文章
- BZOJ4943 NOI2017蚯蚓排队(哈希+链表)
能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂 ...
- [Bzoj4943][Noi2017]蚯蚓(hash)
4943: [Noi2017]蚯蚓 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 237 Solved: 110[Submit][Status][D ...
- 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$ :将 ...
- BZOJ4943 [NOI2017] 蚯蚓
题目描述 蚯蚓幼儿园有nn 只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从11 到nn 的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示,根据入园要求,所有蚯蚓的长 ...
- [NOI2017]蚯蚓排队 hash
题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...
- 洛谷3823 [NOI2017] 蚯蚓排队 【哈希】
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合 ...
- P3823_[NOI2017]蚯蚓排队 哈希+脑子
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
随机推荐
- linux查找重复文件
>/dev/ >/dev/null|grep 02a42c7a845094a8904f7b3faf686b81 uniq -d, --repeated only print duplica ...
- Java——socket
Server: import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public cla ...
- Mybatis学习笔记16 - bind标签
1.${}拼串进行模糊查询,不安全 示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import java ...
- Android官方架构组件介绍之LiveData(二)
LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...
- CentOS 7 修改root 密码
环境: 1.重启系统在加载内核的地方按e,编辑启动脚本 2.将ro crashkernel = auto 所在地的 ro 替换为 rw init=/sysroot/bin/sh 3.修改完成后用Ctr ...
- hash冲突解决和javahash冲突解决
其实就是四种方法的演变 1.开放定址法 具体就是把数据的标志等的对长度取模 有三种不同的取模 线性探测再散列 给数据的标志加增量,取模 平方探测再散列 给数据的标志平方,取模 随机探测再散列 把数据的 ...
- jQuery 3 有哪些新东西
jQuery 的横空出世,至今已有十个年头了,而它的长盛不衰显然不是没有理由的.jQuery 提供了极为友好的接口,使得开发者们可以方便地进行 DOM 操作.发起 Ajax 请求.生成动画……不一而足 ...
- C语言答案解析
1.设整型变量 a=2,则执行下列语句后,浮点型变量b的值不为0.5的是( B ) A) b=1.0/a B) b=(float)(1/a) C) b=1/(float)a ...
- IIS下不能下载文件的docx文档,XLSX文档的设置方法(转)
IIS下不能下载文件的docx文档,XLSX文档的设置方法 Office 2007的的界面风格默认格式中都是.DOCX,XLSX,PPTX等等后缀,连结中包含此类文件时,界面风格默认什么打不开的其实只 ...
- MVC切片编程
在商城网站中,用户中心的每个页面都要几乎都要涉及对用户是否登录的判断,为了减少代码重写,可采用切片编程 using System; using System.Collections.Generic; ...