Educational Codeforces Round 80 (Rated for Div. 2)
A
大概猜一下,就在(sqrt{d})附近,枚举一下就行。
B
设(b)有(x)位,那么有(ab+a+b=acdot10^x+b),也就是(b=10^x-1)
也就是(b=) 9或者99或者999或者...的时候,每个a都是一个解;否则无解。
C
两种做法:
1.原题等价于求长度为2m,值域在1~n的非降序列(a_1,a_2,...,a_m,b_m,b_{m-1}...,b_1).从充要性很容易就能证出来。
等价于不定方程(x_1+x_2+...+x_n=2m)的非负整数解的个数,即为(C_{2m+n-1}^{n-1})。
2.dp。有很多种d法,我的就比较暴力。(f(i,j,k))表示考虑前(i)个数,(a_i=j,b_i=k)的方案数。
(f(i,j,k)=sumlimits_{aleq j, bgeq k}f(i-1,a,b)).这玩意二维前缀和打打就(O(1))转移过去了。
D
牛逼的二分搜索。
二分答案(Ans),表示能否满足(mathop{min}limits_{k=1}^mb_kgeq Ans),等价于对(1leq kleq m)都满足(b_kgeq Ans),等价于选择两个(i,j),对每个(k)都满足(max(a_{ik},a_{jk})geq Ans),等价于(a_{ik}geq Ans)或(a_{jk}geq Ans).
对每一行,如果(a_{ik}geq Ans),就把它看成1,否则看成0,实际上就是找是不是存在两行,按位求或的结果是(2^m-1)。打表,单次check是(O(nm+4^m))的,总复杂度为(O((nm+4^m)log a_{max}))。
E
给定一个LRU访问序列,求在整个过程中每个数离队首的最近距离和最远距离。
最近距离很好求。主要是最远距离。举个例子,序列
21535213
观察1的两次访问,之间有5、3、2三个数被访问过,那么1就在这段时间最远被挤到了第四位。也就是说,相邻的一对相同的数之间不同的数字的个数就是它在这段时间内的最远距离。
维护这么一个序列(b_x)和变量(i),表示区间([x,i])之间不同的数的个数。
当(i)从(i-1)变成(i)时,记(a_i)上次出现的位置为(p_i)(如上面那个例子中(p_7=2),1上次出现在第2位),则区间([p_i,i],[p_i-1,i],[p_i-2,i],...)中出现了至少两次(a_i),而区间([p_i+1,i],[p_i+2,i],...,[i,i])中出现且仅出现一次(a_i),都是在(i)这个位置出现的。这些信息是从(i-1)变成(i)之后才得到的。
更新答案就是查询([p_i+1,i])之间有多少个不同的数,也就是查询(b_{p_i+1}).
因此需要对数组(b)维护两种操作:
1.区间([p_i+1,i])加1;
2.单点查询某个值。
线段树搞定。
至于初始时的信息,可以提前假想一个访问序列(n,n-1,...,2,1)来完成。
另外查询区间有多少个不同的数也可以用主席树或者权值线段树做,但我不会,(嗯菜的理直气壮
F
(看完题解了,大概是个上下界费用流?网络流都是让我队友敲的,起床之后再看看能不能找个板子抄上去吧,先空着)
后记
太棒了,又学到许多线段树