zoukankan      html  css  js  c++  java
  • LOJ 北校门外的回忆 倍增+线段树

    正解:倍增+线段树

    解题报告:

    传送门!

    $umm$这题有个对正解毫无启发的部分分还有个正解,都挺神仙的所以我都写了趴$QAQ$

    先说部分分

    可以考虑把$x$向$x+lowbit(x)$连边,然后当$x+lowbit(x)$已经大于$n$了就指向一个超级根

    这样儿每次执行一次$(x,v)$操作就相当于在树上一条链上的每个点全部$xor=v$,然后查询就是单点查询权值

    然后就线段树或者树状数组维护一波就好$QwQ$

    这里可以解决$nleq 2e5$的部分分辣

    然后就港下正解

    首先考虑$k$是奇数有什么特殊性质嘛

    然后就可以发现,其实这个$x+=lowbit(x)$的操作相当于是对它的最后一位的那个数$ imes 2$然后如果要进位就进位嘛

    可以发现,如果k是奇数,那不管$lowbit(x)$怎么$ imes 2$,始终是不会变成$0$的对趴

    那不会变成$0$的话就是说最低有$1$的位置是不变的

    所以依然考虑连边这样子,就会是除了根节点以外所有点都是只有唯一父亲和唯一儿子节点的,也就是说去掉根节点它就是很多条链

    然后再看这个操作,就相当于是对这条链上的后缀全部异或$v$

    所以用个树状数组或者线段树维护一下就好$QwQ!$

    然后继续考虑$k$是偶数怎么搞

    设$k=pcdot 2^q$

    可以发现当$x$是$2^q$的倍数的时候它同样是会在一条链上的,原因很显然昂就可以考虑$x$和$k$同时除以$2^q$然后$k$就变成奇数了就一样的道理了嘛

    所以只要对$x$不是$2^q$的倍数的维护一下就好

    然后下面详细说下对于$x$不是$2^q$的倍数的,说它要维护是因为它不能保证一直$ imes 2$之后能保持在一条链上嘛,但是可以这么想,我每次都是$ imes 2$,设$x=tcdot 2^w$,因为现在已知$w<q$了,那么就知道每次$\%k$是不会导致$w$变小的,那相当于就每次都是$w++$,那当$w$加到了$q$的时候就满足$x$是$2^q$的倍数了就说已经跳到链上了,就可以继续当做上面一种情况搞就成了

    然后瞎分析一下复杂度,,,其实我不会证,所以下面这段只是搬运一下,,,

    考虑每暴力走一步最低非零位值包含的$2$的因子个数就会$+1$,那么在最低位不变的情况下最坏只需要暴力走$p$次

    而最低非零位就发生了改变的次数是小于等于$log_k n$次的,所以总复杂度是$O(log_2 n)$

    好以上是,$nleq 2e5$,为什么$nleq 1e9$要特殊考虑呢,因为本来上面这个我直接树状数组或者线段树维护一波就欧克

    然而,当$nleq 1e9$的时候树状数组是开不下了的,要考虑用个离散化+树状数组或者动态开点线段树或者平衡树解决

    然后唯一的问题就变成了怎么确定一个点所在的链,这个可以通过确定链的链首确定

    咕咕咕咕咕咕.

  • 相关阅读:
    Linux 修改最大线程数
    Openresty+Nginx+Lua+Nginx_http_upstream_check_module 搭建
    SSDB 性能测试
    面向对象:类的成员
    封装,多态,类的约束,super()深入了解
    面向对象:继承
    面向对象:类的空间问题,类之间关系
    面向对象初识
    软件开发规范
    模块(四)包和logging日志
  • 原文地址:https://www.cnblogs.com/lqsukida/p/10518204.html
Copyright © 2011-2022 走看看