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

能看懂题就能想到正解.维护所有长度不超过k的数字串的哈希值即可,用链表维护一下蚯蚓间连接情况.由于这样的数字串至多只有nk个,计算哈希值的总复杂度为O(nk),而分裂的复杂度为O(ck^2),询问复杂度为O(Σ|s|).于是总复杂度为O(nk+ck^2+Σ|s|). 手写哈希注意插入元素时考虑清楚,如果没有哈希冲突不需要更新哈希使用的链表,所以特判一下. #include<iostream> #include<cstdio> #include<cmath> #inclu…
题面:洛谷 题解: 我们暴力维护当前所有队伍内的所有子串(长度k = 1 ~ 50)的出现次数. 把每个子串都用一个hash值来表示,每次改变队伍形态都用双向链表维护,并暴力更新出现次数. 现在考虑复杂度. 如果只有连接,没有断开,那么复杂度为不同的子串个数:50n(注意只要O(n)预处理前缀和后缀hash就可以做到O(1)得到一个子串的hash值) 如果有断开,那么最多就每断开一次就对应要再重连一次.所以复杂度最多增加2500 * 断开次数,而断开次数1e3.... 所以复杂度就是正确的了.…
https://www.lydsy.com/JudgeOnline/problem.php?id=4943 http://uoj.ac/problem/315 https://www.luogu.org/problemnew/show/P3823#sub 题面太长自己看吧orz. 参考:洛谷题解. 用链表暴力维护每个蚯蚓,每次合并和分离只对k*k的元素有影响,哈希一下存起来query时候比较就好了. 没了. (具体复杂度我不会证明,以及bzoj卡空间,正常的哈希表空间总觉得不能开如代码所示的这么…
题目分析: 从$\sum|S|$入手.共考虑$\sum|S|$个$f(t)$.所以我们要一个对于每个$f(t)$在$O(1)$求解的算法.不难想到是哈希. 然后考虑分裂和合并操作.一次合并操作要考虑合并点之前的$O(k)$个点向后衔接的哈希值.共$O(k^2)$.看似超时实则不然.一个串最多$O(nk)$个哈希结果,所以均摊入手. 对于分裂和重合并不能均摊,所以多了一个$O(ck^2)$. 这题的合并和分裂只和合并点和分裂点有关,而这个信息是给出的,所以不需要额外使用数据结构维护结果. 时间复杂…
题目描述 给出 $n$ 个字符,初始每个字符单独成字符串.支持 $m$ 次操作,每次为一下三种之一: $1\ i\ j$ :将以 $i$ 结尾的串和以 $j$ 开头的串连到一起. $2\ i$ :将 $i$ 所在串从 $i$ 位置和 $i$ 下一个位置之间断开. $3\ S\ k$ :对于字符串 $S$ 每个长度为 $k$ 的子串,统计它在这 $n$ 个字符组成所有字符串中出现的次数,求所有统计结果的乘积模 $998244353$ 的结果. $n\le 2\times 10^5$ ,$m\e5\…
题面:http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf 正解:字符串$hash$. 我在考场上写了个$map$的$hash$被卡成$40$分,然后改成挂链版本的就$AC$了..$mdzz$,以后$hash$再也不写$map$了.. 我们考虑使用链表来表示字符间的关系,合并和分裂都用链表来表示,这样我们可以快速找到两个字符的前$k$个和后$k$个字符. 注意到每次只会增加或减少$k^{2}$个字符串,那么我们直接把这些字符串$hash$起来…
之前就写过一遍,今天却写挂了,查了半天发现是数组名写错啦$qwq$ 观察到$K$很小,所以使得我们可以哈希(怎么什么都能哈希$qwq$).我们把长度小于等于$50$的子串扔到哈希表里,并统计出现次数,注意每次合并和分离时,只加入或删除与断开点距离小于等于$50$的:因为其他子串长度太长,或是已经在前几次中被添加在哈希表里了. #include<cstdio> #include<iostream> #include<algorithm> #include<cstri…
题目链接 洛谷P3832 题解 字符串哈希然后丢到hash表里边查询即可 因为\(k \le 50\),1.2操作就暴力维护一下 经复杂度分析会发现直接这样暴力维护是对的 一开始自然溢出WA了,还以为是哈希冲突,改成双哈希后依旧WA 后来才发现是sb了漏了一句QAQ 不卡自然溢出 #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorith…
嘟嘟嘟 现在看来这道题还不是特别难. 别一看到字符串就想SAM 看到\(k\)很小,所以我们可以搞一个单次修改复杂度跟\(k\)有关的算法. 能想到,每一次断开或链接,最多只会影响\(k ^ 2\)个长度为\(k\)的区间.所以我们开一个哈希表,每一次拼接时就往哈希表里加入\(k ^ 2\)个新的哈希值,断链的时候就把这些哈希值减去.然后查询的时候只要扫一遍\(s\),每遇到长度为\(k\)的子串就再查一下. 具体的操作要用到链表,对于每一个节点分别维护一个pre和suf指针即可. #inclu…
这题看题面感觉挺玄学的,但其实会挂链式hash就能暴力切了,就是纸老虎,考察选手的语文水平.不过三年没写挂链hash也应该写一下了…… 首先模数设成自然溢出ull,然后挂链时的模数取2^24.然后就可以直接hash了.对于3操作直接O(Σ|S|)询问即可,对于1.2操作,直接暴力加.减长度不超过50的字符,毕竟k<=50,这是个关键性条件.所以暴力能切了. 下面分析时间复杂度:先假设没有2操作,因为每一个位置只有长度不超过50的,每次加的数量也是不超过50的,这样总复杂度是均摊O(nk)的:再考…