原题链接

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

考虑复杂度。

首先在删除时由于保证了 c<=1000 所以这部分复杂度是O(ck2)的。

插入时,如果插入操作很慢只有可能是连接两个长度不小于k的串,而长度不小于k的串最多有n/k个,所以这部分复杂度是O(nk)的

所以总复杂度是O(nk+ck2+|s|)。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
inline void read(int &re)
{
char ch=getchar();int g=1;
while(ch<'0'||ch>'9') {if(ch=='-')g=-1;ch=getchar();}
re=0;
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+(ch^48),ch=getchar();
re*=g;
}
typedef long long ll;
typedef double db;
typedef unsigned long long ul;
const ul bas=7u;
const ll mod=998244353;
const ul mod2=99999971u;
const int N=200050;
int head[N],tail[N],cnt=0,nex[20050000],fir[100000000];
int num[20050000];
ul hax[20050000];
char leng[N]; inline ul qpow(ul a,int n)
{
ul ans=1;
for(;n;n>>=1,a=a*a) if(n&1) ans=ans*a;
return ans;
} inline void insert(ul x)
{
ul m=x%mod2;
int u=fir[m];
if(!u)
{
fir[m]=++cnt; hax[cnt]=x;
num[cnt]++; return ;
}
if(hax[u]==x) {num[u]++;return ;}
while(nex[u])
{
u=nex[u];
if(hax[u]==x) {num[u]++; return ;}
}
cnt++;
nex[u]=cnt;
hax[cnt]=x; num[cnt]++;
} inline void del(ul x)
{
ul m=x%mod2;
int u=fir[m];
while(u)
{
if(hax[u]==x) {num[u]--;return ;}
u=nex[u];
}
} inline int query(ul x)
{
ul m=x%mod2;
int u=fir[m];
while(u)
{
if(hax[u]==x) return num[u];
u=nex[u];
}
return 0;
}
char a[10000050];
int n,m; int main()
{
#ifndef ONLINE_JUDGE
freopen("queue.in","r",stdin);freopen("queue.out","w",stdout);
#endif
int i,j,opt,x,y,k;
read(n);read(m);
for(i=1;i<=n;++i)
{
read(opt),leng[i]=opt+48;
ul has=leng[i]-48u;
insert(has);
}
while(m--)
{
read(opt);
if(opt==1)
{
read(x);read(y);//--x y--
tail[x]=y;head[y]=x;
int u=x,v;
for(i=1;i<=50-2&&head[u];++i) u=head[u];
for(;u!=y;u=tail[u])
{
bool can=0;
v=u;
ul has=0;
has=leng[u]-48u;
for(i=1;i<50;++i)
{
v=tail[v];
if(!v) break;
has=has*bas+leng[v]-48u;
if(v==y||can)
{
can=1;
insert(has);
}
}
}
}
else if(opt==2) // --x || y--
{
read(x);
int u=x,v;
y=tail[x];
for(i=1;i<=50-2&&head[u];++i) u=head[u];
for(;u!=y;u=tail[u])
{
bool can=0;
v=u;
ul has=leng[u]-48u;
for(i=1;i<50;++i)
{
v=tail[v];
if(!v) break;
has=has*bas+leng[v]-48u;
if(v==y||can)
{
can=1;
del(has);
}
}
}
head[y]=0;tail[x]=0;
}
else
{
ll ans=1;
scanf("%s",a);read(k);
int len=strlen(a); ul has=0,powbas=qpow(bas,k-1);
for(i=0;i<k;++i) has=has*bas+a[i]-48u;
ans=ans*(ll)query(has);
for(i=1;i<=len-k;++i)
{
has=(has-(a[i-1]-48u)*powbas)*bas+a[i+k-1]-48u;
ans=ans*(ll)query(has)%mod;
}
printf("%lld\n",ans);
}
}
return 0;
}

NOI2017蚯蚓排队的更多相关文章

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

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

  2. [NOI2017]蚯蚓排队 hash

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

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

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

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

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

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

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

  6. bzoj4943 [Noi2017]蚯蚓排队

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

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

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

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

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

  9. [NOI2017]蚯蚓排队

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

  10. [NOI2017]蚯蚓排队(链表+hash)

    这题看题面感觉挺玄学的,但其实会挂链式hash就能暴力切了,就是纸老虎,考察选手的语文水平.不过三年没写挂链hash也应该写一下了…… 首先模数设成自然溢出ull,然后挂链时的模数取2^24.然后就可 ...

随机推荐

  1. MySQL之COUNT(*)性能到底如何?

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 前言 在实际开发过程中,统计一个表的数据量是经常遇到 ...

  2. DolphinScheduler JSON拆解详解

    本次活动邀请DolphinScheduler社区活跃贡献者,开源积极分子,现就职于政采云大数据部门,从事大数据平台架构工作的李进勇同学给大家分享相关内容. 同时也特别感谢示说网对本次直播活动的大力支持 ...

  3. Luogu2251 质量检测 (ST表)

    我怎么开始划水了... #include <iostream> #include <cstdio> #include <cstring> #include < ...

  4. Hive存储格式之RCFile详解,RCFile的过去现在和未来

    我在整理Hive的存储格式和压缩格式,本来打算一篇发出来,结果其中一小节就有很多内容,于是打算写成Hive存储格式和压缩格式系列. 本节主要讲一下Hive存储格式最早的典型的列式存储格式RCFile. ...

  5. git使用的一些坑和新得(一)

    这是一个坑 你要知道作为一个新手对git的使用还处于摸索状态 今天就将这样的坑分享给大家 昨天,接到任务将代码发到远程仓库里.于是,我就天真的按步骤提交了! 然后就: To https: ! [rej ...

  6. ASP.NET Core自定义中间件的方式

    ASP.NET Core应用本质上,其实就是由若干个中间件构建成的请求处理管道.管道相当于一个故事的框架,而中间件就相当于故事中的某些情节.同一个故事框架采用不同的情节拼凑,最终会体现出不同风格的故事 ...

  7. Excel 单元格的相对引用和绝对引用

    引用方式 单元格的地址由该单元格所在的行号和列标构成,一个引用代表工作表上的一个或者一组单元格,指明公式中数据所在的位置. 编号 消费记录 价格 1 乒乓球 1 2 火腿肠 2 3 乒乓球 1 4 羽 ...

  8. 快速搭建 SpringCloud Alibaba Nacos 配置中心!

    Spring Cloud Alibaba 是阿里巴巴提供的一站式微服务开发解决方案,目前已被 Spring Cloud 官方收录.而 Nacos 作为 Spring Cloud Alibaba 的核心 ...

  9. 部署nfs

      NFS可以让服务端跟客户端通过网络共享主机磁盘上的一些数据,主要是在unix和linux系统上实现的一种文件共享方式.   我们可以简单的将NFS看做是一个文件服务器 (file server) ...

  10. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...