zoukankan      html  css  js  c++  java
  • CF809C

    终于把这题 A 掉了,感动中国(

    做这题也是一波三折啊……几天前想的时候想假掉了,交上去 T 了,然后咕了好几天一直咕到现在。然后这数位 DP 又不是一般的难写,写的过程中心态崩过几次。然后又不是一般的难调,调出来之后交上去又 WA 了……然后发现是爆 ll 了,改成 __int128_t 上去,又 CE 了……只好手动把爆炸的地方改过来才 AC。


    Portal

    首先打个表发现这是一个分形,形式化的表述就是 (a=egin{bmatrix}a&a+n_a\a+n_a&aend{bmatrix})。然后我就直接递归了,写得像二维线段树一样,以为是二次对数的。但其实这个是假的,因为二维线段树是横着竖着各分为若干个整区间,横竖独立,而这个除此之外还要满足横竖相等(即是个正方形)。

    然后就自爆了,就看题解了。发现一个结论:(a_{i,j}=(i-1)oplus(j-1)+1)。那么到底怎么才能发现这个结论我也是不知道的,因为我要智商没智商,要眼力没眼力。

    我们考虑将所求问题二位前缀和一下,那么问题归约到求 (sumlimits_{i=0}^xsumlimits_{j=0}^y[ioplus j<k]((ioplus j)+1))。这也是个比较难的问题。考虑类似数位 DP(二进制)地统计答案:将 (x,y) 分别拆成位数比原数低的、和原数的一个前缀后面随便加的一些,这样每部分都是一个固定的前缀后面有若干位随便放的这个形式,并且数量是对数级别的。现在我们只要求,两个这样形式的数的上面那个 (sum) 的值是多少,并且还要是常数时间,这样总时间复杂度是二次对数。

    这个就分类小讨论一下即可。注意到局面是下面这个样子的:

    .----.----------.
    | h1 |    z1    |
    .----.-----.----.
    |    h2    | h2 |
    .----------.----.
    |        k      |
    .---------------.
    

    那么显然可以分为三段。第一段上下的异或和是固定的,那么就讨论一下与 (k) 的这段的大小。如果大那就为 (0),如果小那就后面随便取(这个很容易算出式子,等差数列也可以搞定),如果相等就继续往下。然后看第二段,这个第一个数的部分是自己取的,第二个数的部分是固定的。于是分小于和等于 (k) 这部分两种加起来。小于的话后面随便取,容易列式;等于的话,后面要小于,也容易。

    代码异常难写,细节多的一批。我第一遍写完后只有一个错误也是蛮了不起的。

    code

    珍爱生命,远离抄袭!
  • 相关阅读:
    75. Sort Colors
    101. Symmetric Tree
    121. Best Time to Buy and Sell Stock
    136. Single Number
    104. Maximum Depth of Binary Tree
    70. Climbing Stairs
    64. Minimum Path Sum
    62. Unique Paths
    css知识点3
    css知识点2
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/solution-cf809c.html
Copyright © 2011-2022 走看看