CodeForces1208D
也是挺吓人的一道题,我一开始以为给的是每个数字前比它小的数字有几个,然后我就苦苦看不懂样例...
然后我冷静了一下,重新分析,读题,发现给的是每个数字前比它小的数字的和.
这下看懂样例了,可咋做啊?
如果你仔细思考一下,你会发现有个特殊的存在\(1\),它无论在哪一个位置,给定的数字一定是\(0\).
但\(0\)可能并不只有一个,那么我们就要考虑哪一个\(0\)才应该是\(1\).
你考虑有两个\(0\),一个的位置是\(i\),另一个是\(j\),且满足\(i < j\).
这时候,如果说\(i\)这个位置本来是\(1\),那么给定的\(j\)这个位置的数字一定不会是\(0\),与题设矛盾,所以一定是\(j\)是\(1\).
那么我们可以把这个结论推广为:有多个\(0\)存在时,最右边的\(0\)一定是当前最小的数字.
为什么不直接说是\(1\)而说最小的数字呢?看完下面你就明白了.
那么我们继续推广,当确定了\(1\)的时候,就相当于\(2\)的地位和之前的\(1\)一样,于是此时,最右边的\(0\)应当是\(2\),以此类推.
至于最右边的\(1\),随便找个什么数据结构维护一下就好了.
我这里是采用了线段树,维护区间最小值,同时维护最小值的位置.
至于怎么找最右边的也很简单,每次遇到相等的就右边走就行了.
\(Code:\)
#include #include #include #include #include #include #include #include #include #include #include