这题看题面感觉挺玄学的,但其实会挂链式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)的更多相关文章

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

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

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

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

  3. [NOI2017]蚯蚓排队 hash

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

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

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

  5. LOJ 2303 「NOI2017」蚯蚓排队——链表+哈希表

    题目:https://loj.ac/problem/2303 想到合并的时候可以只考虑接口附近的50个,但不太会分析复杂度,而且没有清楚地想到用哈希值对应个数. 看了题解才会…… 一直想用 splay ...

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

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

  7. bzoj4943 [Noi2017]蚯蚓排队

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

  8. [NOI2017]蚯蚓排队

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

  9. P3823_[NOI2017]蚯蚓排队 哈希+脑子

    之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数, ...

随机推荐

  1. use matplotlib to draw scatter plot

    There are many pionts in this kind of table. How to do it? We can use scatter() to draw it. Code: im ...

  2. P 1008 数组元素循环右移问题

    转跳点:

  3. 文本编辑器vim/vi——命令模式

    一个完整的指令的标准格式: Linux通用的格式——#指令主体(空格) [选项](空格) [操作对象] 一个指令可以包含多个选项,操作对象也可以是多个. vim指令: 指令:vim   (vim是一款 ...

  4. cudaThreadSynchronize()

    // 调用CUDA kernel 是非阻塞的,调用kernel语句后面的语句不等待kernel执行完,立即执行.所以在 call_kernel(see kernel.cu) 中执行 m5op.dump ...

  5. springboot - 使用ErrorAttributes 在我们自定义的 ErrorController中

    1.概览 基于<springboot - 映射 /error 到自定义且实现了ErrorController的Controller>改造,仅将MyCustomErrorController ...

  6. python语法技巧

    目录: 7.python break continue用法 1.三元表达式 2.用列表推导式来取代map和filter 3.函数式编程 4.fluent python 阅读笔记 5.enum库用法 6 ...

  7. C++基础--虚函数和纯虚函数

    虚函数的一种重要的应用是在子类重写父类方法上,一般都是在父类中声明的时候用关键字virtual修饰. 在C++中,一个父类的对象指针是可以指向子类的实例化对象,这个时候可以用该对象指针来访问父类的成员 ...

  8. 剑指offer_1.19_Day_3

    替换空格 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. Javascript_V8 f ...

  9. 二十五、CI框架URL辅助函数之base_url函数

    一.在UI根目录新建一个pic目录,里面放一个图片,如下 二.在我们打View里面写入一下代码,base_ur函数返回的是网站根目录,代码见附图: 三.两种写法,显示效果如下: 四.我们查看浏览器的源 ...

  10. 高分Essay写作需注意以下几个细节

    目前为止,已经有很多同学问我这个了,所以这次专门来讨论下这个问题.英语essay能达到预期分数吗,答案是肯定的,甚至会超出预期,但是必须注意到几方面,越是细节问题,越容易导致丢分,所以请重视-! 一. ...