Brief Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两个长度相同的区间,表示子串Sl1Sl1+1Sl1+2...Sr1与Sl2Sl2+1Sl2+2...S r2完全相同.比如n=6时,某限制条件l1=1,r1=3,l2=4,r2=6,那么123123,351351均满足条件,但是12012,13 1141不满足条件,前者数的长度不为6,后者第二位与第五…
[BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增) 题面 有一个n位的十进制数a(无前导0),给出m条限制,每条限制\((l_1,r_1,l_2,r_2)(保证r_1-l_1=r_2-l_2)\)表示这个数的第\([l_1,r_1]\)位与\([l_2,r_2]\)位相同.问有多少个这样的数满足条件,答案取模\(10^9+7\), \(n \leq 10^5\) 分析 约定:我们把十进制数a的每一位从高到低称为第1位,第2位...,记为\(a_i\) 首先…
P3295 [SCOI2016]萌萌哒 题面 题目描述 一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \cdots S_n\) 表示,其中 \(S_i\) 表示数的第 \(i\) 位, \(S_1\) 是数的最高位.告诉你一些限制条件,每个条件表示为四个数, \(l_1,r_1,l_2,r_2\) ,即两个长度相同的区间,表示子串 \(S_{l_1}S_{l_1+1}S_{l_1+2} \cdots S_{r_1}\) 与 \(S_{l_2}S_{l_2+1}S_{l_2+2} \…
传送门 题意:长为$n \le 10^5$的数字,给出$m \le 10^5$个限制$[l1,r1]\ [l2,r2]$两个子串完全相等,求方案数 把所有要求相等的位置连起来,不就是$9*10^{连通块个数}$嘛 但是最坏情况要连$nm$次啊 有很多都是重复的太浪费了 于是各种乱搞,甚至想了一下分块,即使能减少边的条数也不能减少计算时会走的边的次数 然后看题解,竟然是用倍增来优化 有道理啊,分块太死板了,倍增的话就可以灵活的得到每个区间 $fa[i][j]$表示从i开始$2^j$个数的区间的父亲…
题目:https://www.luogu.org/problemnew/show/P3295 当要连的边形如 “一段区间内都是 i 向 i+L 连边” 的时候,用并查集优化连边. 在连边的时候,如果要连的区间已经有一部分连成这个样子了,就希望跳过这一段. 想倍增那样跳过已经连好的部分.用并查集实现. 建 logn 个并查集,第 i 个并查集里 x 和 y 连通表示 \( [x,x+2^i-1] \) 和 \( [y,y+2^i-1] \) 已经连成了的样子. 那么要连 \( [l1,r1] \)…
传送门 一个朴素的做法就是暴力连边并查集,可是这是\(O(n^2)\)的.发现每一次连边可以看成两个区间覆盖,这两个区间之间一一对应地连边.可线段树对应的两个节点的size可能不同,这会导致"一一对应"的条件在线段树上失效.所以我们需要使用ST表来完成连边. 对原序列建好ST表,对于每一个修改将两个区间覆盖到ST表上然后两两之间连边.注意在ST表上连边的两个区间要对应,即如果ST表上对应\([l,r]\)的区间与对应\([L,R]\)的区间连了边,意味着对于\(\forall i \i…
题目链接 Description 一个长度为\(n\)的大数,用\(S_1S_2S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每个条件表示为四个数,\(l_1,r_1,l_2,r_2\),即两个长度相同的区间,表示子串\(S_{l1}S_{l1+1}S_{l1+2}...S_{r1}\)与\(S_{l2}S_{l2+1}S_{l2+2}...S_{r2}\)完全相同. 问满足以上所有条件的数有多少个. 思路 参考 https…
题目链接 BZOJ4569 题解 倍增的思想很棒 题目实际上就是每次让我们合并两个区间对应位置的数,最后的答案\(ans = 9 \times 10^{tot - 1}\),\(tot\)是联通块数,因为要去前导\(0\),首位不为\(0\)即可 如何快速合并两个区间? 倍增! 每次合并两个区间,我们就利用倍增分成\(logn\)个区间,先用并查集维护其联通性 合并完之后,由大区间推向小区间,将每个倍增的大区间分成两半,分别和其联通块的代表区间的两半合并 #include<algorithm>…
一个显然的暴力是用并查集记录哪些位之间是相等的.但是这样需要连nm条边,而实际上至多只有n条边是有用的,冗余过多. 于是考虑优化.使用类似st表的东西,f[i][j]表示i~i+2^j-1与f[i][j]~f[i][j]+2^j-1连接起来了,也就是把这一大段看成一个点所建立的并查集.那么每个限制只要拆成两段就可以了.最后查询的时候,需要把信息下传,即f[i][j]下传到f[i][j-1]和f[i+2^(j-1)][j-1],表示这两段各自分别对应.于是复杂度变成了O(nlognαn).这个做法…
传送门 对于每个限制,使用倍增的二进制拆分思想,用并查集数组fa[i][j]" role="presentation" style="position: relative;">fa[i][j]fa[i][j]表示从i" role="presentation" style="position: relative;">ii开始,延伸2j" role="presentation&q…