Description

题库链接

蚯蚓幼儿园有 \(n\) 只蚯蚓。幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演。

所有蚯蚓用从 \(1\) 到 \(n\) 的连续正整数编号。每只蚯蚓的长度可以用一个正整数表示,根据入园要求,所有蚯蚓的长度都不超过 \(6\) 。神刀手希望这些蚯蚓排成若干个队伍,初始时,每只蚯蚓各自排成一个仅有一只蚯蚓的队伍,该蚯蚓既在队首,也在队尾。

神刀手将会依次进行 \(m\) 次操作,每个操作都是以下三种操作中的一种:

1.给出 \(i\) 和 \(j\) ,令 \(i\) 号蚯蚓与 \(j\) 号蚯蚓所在的两个队伍合并为一个队伍,具体来说,令 \(j\) 号蚯蚓紧挨在 \(i\) 号蚯蚓之后,其余蚯蚓保持队伍的前后关系不变。
2.给出 \(i\) ,令 \(i\) 号蚯蚓与紧挨其后的一只蚯蚓分离为两个队伍,具体来说,在分离之后, \(i\) 号蚯蚓在其中一个队伍的队尾,原本紧挨其后的那一只蚯蚓在另一个队伍的队首,其余蚯蚓保持队伍的前后关系不变。
3.给出一个正整数 \(k\) 和一个长度至少为 \(k\) 的数字串 \(s\) ,对于 \(s\) 的每个长度为 \(k\) 的连续子串 \(t\) (这样的子串共有 \(|s| - k + 1\) 个,其中 \(|s|\) 为 \(s\) 的长度),定义函数 \(f(t)\) ,询问所有这些 \(f(t)\) 的乘积对 \(998244353\) 取模后的结果。其中 \(f(t)\) 的定义如下: 对于当前的蚯蚓队伍,定义某个蚯蚓的向后 \(k\) 数字串为:从该蚯蚓出发,沿队伍的向后方向,寻找最近的 \(k\) 只蚯蚓(包括其自身),将这些蚯蚓的长度视作字符连接而成的数字串;如果这样找到的蚯蚓不足 \(k\) 只,则其没有向后 \(k\) 数字串。例如蚯蚓的队伍为 \(10\) 号蚯蚓在队首,其后是 \(22\) 号蚯蚓,其后是 \(3\) 号蚯蚓(为队尾),这些蚯蚓的长度分别为 \(4\) 、 \(5\) 、 \(6\) ,则 \(10\) 号蚯蚓的向后 \(3\) 数字串 为456, \(22\) 号蚯蚓没有向后 \(3\) 数字串,但其向后 \(2\) 数字串为56,其向后 \(1\) 数字串为5。

而 \(f(t)\) 表示所有蚯蚓中,向后 \(k\) 数字串恰好为 \(t\) 的蚯蚓只数。

保证 \(n \leqslant 2 \times 10^5,\ m \leqslant 5 \times 10^5,\ k \leqslant 50\) 。设 \(\sum |S|\) 为某个输入文件中所有询问的 s 的长度总和,则 \(\sum |S| \leqslant 10^7\) 。 设 \(c\) 为某个输入文件中形如 2 i 的操作的次数,则 \(c \leqslant 10^3\) 。

Solution

由于 \(k\) 比较小,直接 \(hash\) 就行了。复杂度是正确的,因为整个字符串需被 \(hash\) 的子串是 \(O(nk)\) 的。由于 \(c\leq 10^3\) ,所以修改的字符串复杂度是 \(O(ck^2)\) 的。

总复杂度是 \(O\left(nk+ck^2+\sum|S|\right)\) 。

Code

#include <bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N = 2e5+5, LEN = 1e7+5, yzh = 998244353, p = 12456791, base = 31;
void gi(int &x) {
char ch = getchar(); x = 0;
for (; ch < '0' || ch > '9'; ch = getchar());
for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x<<1)+(x<<3)+ch-48;
} char ch[LEN];
int n, m, l[N], lst[N], nxt[N], opt, x, y, k;
ull bin[N], tmp;
struct hash_table {
int cnt[p]; ull ky[p];
void insert(ull x, int val) {
int loc = x%p;
while (true) {
if (ky[loc] == 0 || ky[loc] == x) {cnt[loc] += val, ky[loc] = x; break; }
++loc; if (loc == p) loc = 0;
}
}
int count(ull x) {
int loc = x%p;
while (true) {
if (ky[loc] == 0 || ky[loc] == x) return cnt[loc];
++loc; if (loc == p) loc = 0;
}
}
}mp; void merge() {
int t = 48, loc = x;
while (t-- && lst[loc]) loc = lst[loc];
lst[y] = x, nxt[x] = y;
for (; lst[loc] != x; loc = nxt[loc]) {
bool flag = 0; t = loc; tmp = 0;
for (int j = 1; j <= 50 && t; j++, t = nxt[t]) {
tmp = tmp*base+l[t];
if (flag) mp.insert(tmp, 1);
if (t == x) flag = 1;
}
}
}
void split() {
int t = 48, loc = x; y = nxt[x];
while (t-- && lst[loc]) loc = lst[loc];
for (; lst[loc] != x; loc = nxt[loc]) {
bool flag = 0; t = loc; tmp = 0;
for (int j = 1; j <= 50 && t; j++, t = nxt[t]) {
tmp = tmp*base+l[t];
if (flag) mp.insert(tmp, -1);
if (t == x) flag = 1;
}
}
lst[y] = nxt[x] = 0;
}
int query() {
int n = strlen(ch+1), ans = 1; tmp = 0;
for (int i = 1; i <= n; i++) {
tmp = tmp*base+ch[i]-48;
if (i > k) tmp -= 1ll*(ch[i-k]-48)*bin[k];
if (i >= k) ans = 1ll*ans*mp.count(tmp)%yzh;
}
return ans;
}
void work() {
gi(n), gi(m); bin[0] = 1;
for (int i = 1; i <= n; i++) gi(l[i]), mp.insert(l[i], 1);
for (int i = 1; i <= 50; i++) bin[i] = bin[i-1]*base;
while (m--) {
gi(opt);
if (opt == 1) gi(x), gi(y), merge();
else if (opt == 2) gi(x), split();
else scanf("%s", ch+1), gi(k), printf("%d\n", query());
}
}
int main() {
freopen("queue.in", "r", stdin);
freopen("queue.out", "w", stdout);
work(); return 0;
}

[NOI 2017]蚯蚓排队的更多相关文章

  1. 【NOI】2017 蚯蚓排队(BZOJ 4943,LOJ 2303) 模拟+hash

    [题目]#2303. 「NOI2017」蚯蚓排队 [题意]给定n条长度不超过6的蚯蚓,初始各自在一个队伍.m次操作:1.将i号蚯蚓和j号蚯蚓的队伍合并(保证i为队尾,j为队首).2.将i号蚯蚓和它后面 ...

  2. 【BZOJ4943】【NOI2017】蚯蚓排队(哈希)

    [BZOJ4943][NOI2017]蚯蚓排队(哈希) 题面 BZOJ 洛谷 UOJ 题解 记得去年看网络同步赛的时候是一脸懵逼的. 昨天看到\(zsy\)做了,今天就看了看.. 这不是\(Hash\ ...

  3. LOJ2303 「NOI2017」蚯蚓排队

    「NOI2017」蚯蚓排队 题目描述 蚯蚓幼儿园有$n$只蚯蚓.幼儿园园长神刀手为了管理方便,时常让这些蚯蚓们列队表演. 所有蚯蚓用从$1$到$n$的连续正整数编号.每只蚯蚓的长度可以用一个正整数表示 ...

  4. NOI 2017滚粗退役记

    NOI 2017 游记 又到了OIer退役了的季节 Day -1 今天是报到日. 中午11点多的动车.动车上和dick32165401和runzhe2000谈笑风生.顺便用dick32165401的流 ...

  5. 「NOI2017」蚯蚓排队 解题报告

    「NOI2017」蚯蚓排队 这题真的草 你考虑\(k\)这么小,每次合并两个串,增加的有用串的数量是\(O(k^2)\)的,暴力加入这些串,求一下这些串的Hash值,塞到Hash表里面去 这里采用类似 ...

  6. NOI 2017 Day1 题解

    被虐爆了... T1 整数 题目传送门 Description 有一个整数 \(x\),有 \(n\) 此操作,每次操作为以下两种情况: 给出 \(a,b\),将 \(x\) 加上 \(a\times ...

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

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

  8. [NOI2017]蚯蚓排队 hash

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

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

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

随机推荐

  1. C++标准库第二版笔记 2

    C++标准库第二版笔记 2 微小但重要的语法提升 template表达式内的空格: vector< list<int> >; // OK in each C++ version ...

  2. 过滤器(Filter)、拦截器(Interceptor)、监听器(Listener)

    一.Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servle ...

  3. Chapter6 胞内信号网络

    一.一条从细胞表面到细胞核的通路 二.Ras蛋白处于复杂信号级联的中心位置 胞外信号→酪氨酸激酶受体→Shc→Grb→Sos→Ras 三.酪氨酸的磷酸化控制着许多胞内信号蛋白的定位与活动 Src蛋白的 ...

  4. middleware#52

    错误做法 这道题还是挺有意思的,一开始自己的做法是这样的 const app = { fns: [], callback(ctx) { console.log(ctx) }, use(fn) { th ...

  5. Hibernate3.0配置

    我的系统Win10(64x),Eclipse jee 2018-09 ,Sql2018版本. 以下是Hibernate3.0配置包 链接:https://pan.baidu.com/s/10Kizby ...

  6. socketserver实现FTP

    功能: 1.用户加密认证 2.允许同时多用户登录 3.每个用户有自己的家目录 ,且只能访问自己的家目录 4.对用户进行磁盘配额,每个用户的可用空间不同 5.允许用户在ftp server上随意切换目录 ...

  7. Real World Parsec --- 一个简便易学的 解释器

    学习链接如下: http://bms.tratao.com/desktop/doc/0c3802e4ee404a71407f34996eff98ef 另外的解析器 ANTLR,学过一阵子,比较难,没应 ...

  8. 微服务日志之Spring Boot Kafka实现日志收集

    前言 承接上文( 微服务日志之.NET Core使用NLog通过Kafka实现日志收集 https://www.cnblogs.com/maxzhang1985/p/9522017.html ).NE ...

  9. 【算法】实现字典API:有序数组和无序链表

    参考资料 <算法(java)>                           — — Robert Sedgewick, Kevin Wayne <数据结构>       ...

  10. 【接口时序】2、Verilog实现流水灯及与C语言的对比

    一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE 硬件平台: 1.FPGA型号:XC6SLX45 ...