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

    珍爱生命,远离抄袭!
  • 相关阅读:
    进程池和线程池、协程、TCP单线程实现并发
    GIL全局解释锁,死锁,信号量,event事件,线程queue,TCP服务端实现并发
    进程补充和线程的介绍
    进程的介绍和使用
    异常处理和UDP Socket套接字
    TCP Socket 套接字 和 粘包问题
    网络编程
    面向对象高级——反射和元类
    面向对象三大特性之——多态和一些内置函数
    面向对象-内置方法
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/solution-cf809c.html
Copyright © 2011-2022 走看看