码迷,mamicode.com
首页 > 其他好文 > 详细

【Codeforces Gym 100739 A】Queries

时间:2019-05-11 23:05:22      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:ref   合并   force   lin   运算   sum   line   pre   就是   

题意:给\(n\)个数\(a_{1..n}\),以及\(m\)个询问,每个询问如下:

  • 1 p x表示把第\(p\)位上的数改成\(x\)
  • 2 a b表示找出\(\sum_{a\le l\le r\le b}a_l\ xor\ \ldots\ xor\ a_r\)

思路:线段树。

首先肯定把位拆开来考虑,那么我们建\(10\)棵线段树。

每棵线段树需要维护什么呢?

首先肯定需要维护这一段中这一位的亦或和。

那么我们知道亦或就是自己的逆运算,即\(xorsum(a,b)=xorPrefixSum(b)\ xor\ xorPrefixSum(a-1)\),所以我们需要存储这一段所有的前缀亦或和中为\(1\)\(0\)的。

同时肯定要把答案记录下来。

那么我们的线段树的每个节点长这样:

  • sum,即亦或和
  • odd,即前缀亦或和中为1的个数
  • even,即前缀亦或和中为0的个数
  • ans,即答案。

然后我们看看上推操作。

首先我们的sum=ls.sum^rs.sum

那么我们分ls.sum的情况讨论。

如果ls.sum=0,那么我们的rs.odd会加到odd中,rs.even也是同理。

看ans会有什么变化。

首先我们的ans肯定要从ls.ans和rs.ans中来,然后rs中的even可以和所有的ls中的odd配对,odd也同理。

如果ls.sum=1就应该把所有的rs.even换成odd,odd换成even。

那么我们在查询的时候用zkw线段树的方式,从左边向上走一串,右边走一串,分别"上推"成\(l\)\(r\),最后把\(l\)\(r\)合并即可。

还是不太好写的吧。还有一种想法就是存前后缀的和中有多少\(0\)\(1\)。这样可能自然一点。毕竟和比差总是好的嘛。

【Codeforces Gym 100739 A】Queries

标签:ref   合并   force   lin   运算   sum   line   pre   就是   

原文地址:https://www.cnblogs.com/denverjin/p/10850369.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!