.article-info-tag,button{text-transform:uppercase}.day,.postMeta,.postSticky{position:relative}.postTitle a:link,html{-webkit-tap-highlight-color:transparent}#blog-calendar,.code-copay-btn,.code-hljs-len,.hidden{visibility:hidden}#EntryTag,#blogTitle h1{margin-top:20px}#EntryTag a,.postSticky{background:#6fa3ef}#blogTitle h1 a:hover,.dayTitle a,a,a:active,a:link,a:visited{color:#5c8ec6}#calendar table a:hover,#navList a:hover,.postDesc a:hover,a:active,a:hover,a:link,a:visited,button{text-decora…ryTag a:visited{color:#666}#BlogPostCategory a,#EntryTag a{height:20px;line-height:20px;color:#fff!important;padding:3px 5px;border-radius:3px;margin:2px 5px 0;text-decoration:none;font-size:14px}#BlogPostCategory a:hover,#EntryTag a:hover{transition:all .3s linear 0s;opacity:.8}#topics .postDesc{padding-left:0;width:100%;text-align:left;color:#666;margin-top:5px;background:0 0}.feedbackListSubtitle-louzhu:after,.feedbackListSubtitle:after,.feedbackListSubtitle:before{top:11px;right:100%;left:-1

P5607 [Ynoi2013] 无力回天 NOI2017 题解

\(\text {Description}\)

维护序列,支持区间异或,区间查与一个数的最大异或

\(\text {Solution}\)

我们要求最大异或,首先考虑的就是线性基,但是线性基并不支持区间修改。

所以我们要找一个能支持该操作的数据结构(比如线段树),所以我们可以考虑用线段树套一个线性基。看到这里,你已经能切掉 P4839 P哥的桶 了。但是这道题有一个极为恶心的操作:区间异或。而我们知道线段树并不能处理区间异或的操作(懒标记并不能和加法产生兼容性)

所以我们可以考虑把它转化成单点修改,怎么转化呢?

考虑构造差分数组 \(b\), 满足\(b_i=a_i\oplus a_{i-1}\) (其中 \(\oplus\) 表示异或)

我们可以发现 \(a_i=b_1\oplus b_2 \oplus b_3\cdots b_i\)

也就是说 \(a\)\([l,r]\) 的线性基与 \(a_l\)\(b\)\([l+1,r]\) 的线性基是相等的。

这样子我们就可以通过维护 \(b\) 的线性基来做到单点修改,但是又能维护区间信息了。

梳理一下算法:

1.构建差分数组 \(b\),通过线段树维护差分数组的线性基。

2.用树状数组维护每次询问需要的 \(a_l\),由于 \(b\) 是差分数组,所以等价于求 \(b\) 的前缀和。

具体细节见代码(代码在链接里)。

posted @ 2021-04-08 19:45  feicheng  阅读(33)  评论(0编辑  收藏  举报