赛后回顾
前五题都挺简单的,第五题是个组合数学题,有种解法值得关注一下
第六题没做出来,赛时是考虑用 calc(R)−calc(L−1) 的方式去求出区间 [L,R] 的值,然后考虑对区间大小二分,对于一个特定的区间大小,假设了所有这个大小的区间的值是连续的,然后应该是假了(额,现在仔细想了下,貌似假的很明显,不过赛时第一步就考虑错了也不太可能做出来了)
E
题意
求出n个数的所有排列中包含1和n的所有子区间的个数
解法
假设有 (n−2) 个任意排列的数,在这 (n−2)个数中插入四个空格,分别填入1,n,L,R ,这样就一一对应了所有满足条件的子区间,此时情况数是 (n+2)! 。注意这四个空格左右两侧必须分别是 L,R ,这种放置在四个数的排列中占比是 4!2!,所以最后的答案是 (n+2)!×4!2!=12(n+2)!
F
题意
判断是否存在区间 [L,R] 使得区间内所有数字符串拼接起来的长度等于 n,若存在,求出最小的区间长度,另外有限制 R<m
解法
对于区间 [L,R] ,考虑其涉及的位数区间是 [l,r] (例如对于区间 [648,114514] ,涉及的位数区间就是 [3,6])
那么位数为 4,5 的所有数都是包含的,并且对于特定的位数,每个数的贡献是一样的,总个数也很显然。(例如,位数为 4 的所有数就是 [1000,9999] ,每个数的贡献值都是 4 ,总个数是 9999−1000+1=9000 ,所以位数为 x 的所有数的总贡献值就是 9×10x−1×x)
考虑如何去凑出 n ,可以枚举 l,r ,表示 [L,R] 涉及的位数区间,那么位数区间 [l+1,r−1] 中的所有数都是包含的,那么总贡献就是 ∑x=l+1r−19×10x−1×x ,除此之外还需要考虑位数为 l,r 时的贡献值。
假设位数为 l,r 的个数分别是 x,y 个,那么有等式 l×x+r×y=n′=n−∑x=l+1r−19×10x−1×x
显然可以通过 exgcd 来求解,此外考虑另外一种解法
注意到 l,r 满足这样的限制 1≤l,r≤18,l≤r
改写等式为 l×x=n′−r×y
要令 (n′−r×y)≡0(modl)
考虑枚举 y ,(n′−r×y)modl 的值是存在循环的,n′−r×y≡n′−r×(y+l)(modl)
所以循环节的长度为 l ,而 l≤18 ,所以直接暴力枚举的复杂度也足够通过此题