[NOI2017]蚯蚓排队(链表+hash)
这题看题面感觉挺玄学的,但其实会挂链式hash就能暴力切了,就是纸老虎,考察选手的语文水平。不过三年没写挂链hash也应该写一下了……
首先模数设成自然溢出ull,然后挂链时的模数取2^24。然后就可以直接hash了。对于3操作直接O(Σ|S|)询问即可,对于1、2操作,直接暴力加、减长度不超过50的字符,毕竟k<=50,这是个关键性条件。所以暴力能切了。
下面分析时间复杂度:先假设没有2操作,因为每一个位置只有长度不超过50的,每次加的数量也是不超过50的,这样总复杂度是均摊O(nk)的;再考虑2操作,因为2操作数量很少,而且每次只会至多影响O(k2)个数,因此考虑2操作后,复杂度是O(ck2)的,于是总复杂度是O(nk+ck2+Σ|S|)。注意hash不能用map,要挂链,因为map自带大常数和log,为什么不能unordered_map呢?因为这是NOI,不能用c++11。
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N=5e5+,p=,mod=,gloid=(<<)-;
int n,m,q,a[N],pre[N],nxt[N],cnt[N],f[];
ull h[],pw[];
char s[];
struct Hash{
struct edge{ull x;int v,nxt;}e[];
int hd[gloid+],ecnt;
void add(ull x,int d)
{
int u=x&gloid;
for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x){e[i].v+=d;return;}
e[++ecnt]=(edge){x,d,hd[u]},hd[u]=ecnt;
}
int query(ull x)
{
int u=x&gloid;
for(int i=hd[u];i;i=e[i].nxt)if(e[i].x==x)return e[i].v;
return ;
}
}mp;
void merge()
{
int x,y,L=,R=;scanf("%d%d",&x,&y);
memset(f,,sizeof f);
for(int i=x;i&&L>;i=pre[i])f[--L]=a[i];
for(int i=y;i&&R<;i=nxt[i])f[++R]=a[i];
for(int i=;i<=R;i++)h[i]=h[i-]*p+f[i];
for(int i=L;i<=;i++)
for(int j=;j<=min(R,i+);j++)
mp.add(h[j]-h[i-]*pw[j-i+],);
nxt[x]=y,pre[y]=x;
}
void split()
{
int x,y,L=,R=;scanf("%d",&x),y=nxt[x];
memset(f,,sizeof f);
for(int i=x;i&&L>;i=pre[i])f[--L]=a[i];
for(int i=y;i&&R<;i=nxt[i])f[++R]=a[i];
for(int i=;i<=R;i++)h[i]=h[i-]*p+f[i];
for(int i=L;i<=;i++)
for(int j=;j<=min(R,i+);j++)
mp.add(h[j]-h[i-]*pw[j-i+],-);
nxt[x]=pre[y]=;
}
int query()
{
scanf("%s",s+);
int len=strlen(s+),ret=,k;
scanf("%d",&k);
ull val=;
if(k==)
{
for(int i=;i<=len;i++)ret=1ll*ret*cnt[s[i]]%mod;
return ret;
}
for(int i=;i<=len;i++)
{
val=val*p+s[i];
if(i>k)val-=pw[k]*s[i-k];
if(i>=k)ret=1ll*ret*mp.query(val)%mod;
}
return ret;
}
int main()
{
scanf("%d%d",&n,&q);
pw[]=;for(int i=;i<=;i++)pw[i]=pw[i-]*p;
for(int i=;i<=n;i++)scanf("%d",&a[i]),a[i]+='',cnt[a[i]]++;
while(q--)
{
int op;scanf("%d",&op);
if(op==)merge();
else if(op==)split();
else printf("%d\n",query());
}
}
[NOI2017]蚯蚓排队(链表+hash)的更多相关文章
- 洛谷P3832 [NOI2017]蚯蚓排队 【链表 + 字符串hash】
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为 ...
- BZOJ4943 NOI2017蚯蚓排队(哈希+链表)
能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂 ...
- [NOI2017]蚯蚓排队 hash
题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复 ...
- 【uoj#315/bzoj4943】[NOI2017]蚯蚓排队 Hash
题目描述 给出 $n$ 个字符,初始每个字符单独成字符串.支持 $m$ 次操作,每次为一下三种之一: $1\ i\ j$ :将以 $i$ 结尾的串和以 $j$ 开头的串连到一起. $2\ i$ :将 ...
- LOJ 2303 「NOI2017」蚯蚓排队——链表+哈希表
题目:https://loj.ac/problem/2303 想到合并的时候可以只考虑接口附近的50个,但不太会分析复杂度,而且没有清楚地想到用哈希值对应个数. 看了题解才会…… 一直想用 splay ...
- BZOJ4943 & 洛谷3823 & UOJ315:[NOI2017]蚯蚓排队——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.or ...
- bzoj4943 [Noi2017]蚯蚓排队
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分, ...
- [NOI2017]蚯蚓排队
嘟嘟嘟 现在看来这道题还不是特别难. 别一看到字符串就想SAM 看到\(k\)很小,所以我们可以搞一个单次修改复杂度跟\(k\)有关的算法. 能想到,每一次断开或链接,最多只会影响\(k ^ 2\)个 ...
- P3823_[NOI2017]蚯蚓排队 哈希+脑子
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...
随机推荐
- Web基础之Spring IoC
Spring之IoC 概念 IoC:Inversion of Control,中文通常翻译为"控制反转",它还有一个别名叫做依赖注入(Dependency Injection) ...
- JQuery 动画实现
$(this.div_wrong).show().css({width:"0px", height:"0px"}) .animate({width:&qu ...
- JS+CSS - table 表格固定表头和第一列、内容可滚动 (转载)
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- php.laravel.csrf
概念请自己查 在全局帮助函数库Illuminate\Foundation\helpers.php中有以下几个函数定义,在看过前两个函数实现可以在使用中多少有点帮助. function csrf_fie ...
- ADLS_pppoe 基本设置过程
ADLS_pppoe 设置: ①:开启接口的PPPoe功能——pppoe enable ②:指明接口是拨号池1的成员——pppo-client dial-pool-number ③:创建一个逻辑上的拨 ...
- Elasticsearch全文搜索引擎-PHP使用教程。
1.声明依赖关系: 比方说,你的项目中需要一个php版的elasticsearch框架.为了将它添加到你的项目中(下载),你所需要做的就是创建一个 composer.json 文件,其 ...
- 五十八、SAP中常用预定义数据类型
一.SAP中常用预定义数据类型 注意事项如下: 1.默认的定义数据类型是CHAR. 2.取值的时候C型默认从左取,N型从右取,超过定义长度则截断. 3.C类型,可以赋值数值,也可以赋值字符,还可以混合 ...
- 导出execl
string filepath = Utils.GetMapPath("/upload/excel/"); filepath = filepath + fileName + &qu ...
- 第十篇 Form表单
Form表单 阅读目录(Content) Form介绍 普通的登录 使用form组件 Form那些事儿 常用字段演示 校验 使用Django Form流程 补充进阶 应用Bootstrap样式 批量添 ...
- 【转载】使用driver.findElement(By.id("txtPhoneNum")).getText();获取文本
今天在写自动化测试脚本的时候要获取一个输入框中的文本写了如下脚本: getAndSwitch("http://cas.minshengnet.com:14080/register/eRegi ...