X or What?

符号约定:

  • $\xor$ 表示异或。
  • popcount($x$) 表示非负整数 $x$ 的二进制表示里数字 1 出现的次数。例如,$13 = 1101_2$,则 popcount(13) = 4。

注意到,popcount($a \xor b$) = popcount($a$) + popcount($b$) - 2 * number of positions both $a$ and $b$ are set。

因此,popcount($a \xor b$) 的奇偶性 = (popcount($a$) + popcount($b$)) 的奇偶性。

区间 $[L, R]$ 的异或和的 popcount 为偶数 $\iff$ $L - 1, R$ 这两个前缀的异或和的 popcount 同奇偶。

分别考虑异或和的 popcount 为奇数的前缀、异或和的 popcount 为偶数的前缀。

改变 $A_p$ 对答案的影响:

若 $A_p$ 的 popcount 的奇偶性不变,则答案亦不变,否则 $p, p+1, \dots, n - 1$ 这些前缀的异或和的 popcount 的奇偶性翻转。

解法 1

用线段树维护前缀的异或和的 popcount 的奇偶性。

支持查询:

  • 异或和的 popcount 为偶数的前缀最后一次出现的位置。
  • 异或和的 popcount 为奇数的前缀第一次/最后一次出现的位置。
bool bit_even(int x) {
return (__builtin_popcount(x) & 1) == 0;
} struct node {
int n[2];
int flipped;
void flip() {
swap(n[0], n[1]);
flipped ^= 1;
}
};
const int N = 100005;
node seg[4 * N]; int sum[N];
void push_up(int i) {
int l = i * 2, r = l + 1;
for (int j = 0; j < 2; j++) {
seg[i].n[j] = seg[l].n[j] + seg[r].n[j];
}
} void build (int i, int l, int r) {
seg[i].flipped = 0;
if (l == r) {
seg[i].n[0] = bit_even(sum[l]);
seg[i].n[1] = 1 - seg[i].n[0];
return;
}
int mid = (l + r) / 2;
build(i * 2, l, mid);
build(i * 2 + 1, mid + 1, r);
push_up(i);
} void push_down(int i) {
if (seg[i].flipped) {
int l = i * 2, r = i * 2 + 1;
seg[l].flip();
seg[r].flip();
seg[i].flipped = 0;
}
} int find_first(int v, int i, int l, int r) {
if (seg[i].n[v] == 0) return r + 1;
if (l == r) return l;
push_down(i);
int mid = (l + r) / 2;
int res = find_first(v, i * 2, l, mid);
if (res <= mid) {
return res;
}
return find_first(v, i * 2 + 1, mid + 1, r);
} int find_last(int v, int i, int l, int r) {
if (seg[i].n[v] == 0) return l - 1;
if (l == r) return l;
push_down(i);
int mid = (l + r) / 2;
int res = find_last(v, i * 2 + 1, mid + 1, r);
if (res > mid) {
return res;
}
return find_last(v, i * 2, l, mid);
} void flip(int i, int l, int r, int ql, int qr) {
if (ql > r || qr < l) return;
if (ql <= l && r <= qr) {
seg[i].flip();
return;
}
int mid = (l + r) / 2;
push_down(i);
flip(i * 2, l, mid, ql, qr);
flip(i * 2 + 1, mid + 1, r, ql, qr);
push_up(i);
} int main() {
#ifdef LOCAL
ifstream in("main.in");
cin.rdbuf(in.rdbuf());
#endif
int T; cin >> T;
for (int cas = 1; cas <= T; ++cas) {
cout << "Case #" << cas << ":";
int n, q; cin >> n >> q;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum[i] = sum[i - 1] ^ a[i];
}
build(1, 1, n);
while (q--) {
int p, v;
cin >> p >> v;
++p;
if (bit_even(v) != bit_even(a[p])) {
flip(1, 1, n, p, n);
}
a[p] = v;
cout << " " << max(find_last(0, 1, 1, n), find_last(1, 1, 1, n) - find_first(1, 1, 1, n));
}
cout << endl;
}
return 0;
}

Kick Start 2019 Round D的更多相关文章

  1. kick start 2019 round D T3题解

    ---恢复内容开始--- 题目大意:共有N个房子,每个房子都有各自的坐标X[i],占据每个房子需要一定花费C[i].现在需要选择K个房子作为仓库,1个房子作为商店(与题目不同,概念一样),由于仓库到房 ...

  2. kick start 2019 round D T2题解

    题目大意:由N个房子围成一个环,G个人分别顺时针/逆时针在房子上走,一共走M分钟,每分钟结束,每个人顺/逆时针走到相邻的房子.对于每个房子都会记录最后时刻到达的人(可能是一群人).最终输出每个人会被几 ...

  3. Kick Start 2019 Round A Contention

    $\DeclareMathOperator*{\argmax}{arg\,max}$ 题目链接 题目大意 一排 $N$ 个座位,从左到右编号 $1$ 到 $N$ . 有 $Q$ 个预定座位的请求,第 ...

  4. Kick Start 2019 Round H. Elevanagram

    设共有 $N = \sum_{i=1}^{9} A_i$ 个数字.先把 $N$ 个数字任意分成两组 $A$ 和 $B$,$A$ 中有 $N_A = \floor{N/2}$ 个数字,$B$ 中有 $N ...

  5. Kick Start 2019 Round A Parcels

    题目大意 $R \times C$ 的网格,格子间的距离取曼哈顿距离.有些格子是邮局.现在可以把至多一个不是邮局的格子变成邮局,问每个格子到最近的邮局的曼哈顿距离的最大值最小是多少. 数据范围 $ 1 ...

  6. Kick Start 2019 Round B Energy Stones

    对我很有启发的一道题. 这道题的解法中最有思维难度的 observation 是 For simplicity, we will assume that we never eat a stone wi ...

  7. 【DP 好题】Kick Start 2019 Round C Catch Some

    题目链接 题目大意 在一条数轴上住着 $N$ 条狗和一个动物研究者 Bundle.Bundle 的坐标是 0,狗的坐标都是正整数,可能有多条狗住在同一个位置.每条狗都有一个颜色.Bundle 需要观测 ...

  8. Kick Start 2019 Round F Teach Me

    题目链接 题目大意 有 $N$ 个人,$S$ 项技能,这些技能用 $1, 2, 3, \dots, S$ 表示 .第 $i$ 个人会 $c_i$ 项技能($ 1 \le c_i \le 5 $).对于 ...

  9. Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解

    Google Kick Start 2019 C轮 第一题 Wiggle Walk 题解 题目地址:https://codingcompetitions.withgoogle.com/kickstar ...

随机推荐

  1. ubuntu+tomcat+jenkins+git+maven

    1.下载tomcat.jdk和jenkins.war (下面通过wget下载的jdk-8u231-linux-x64.tar.gz不能用,需要本地下载后上传到服务器)解决Linux上解压jdk报错gz ...

  2. 我在做评论功能时学到的js一些思路

    在提交评论的时候,如何判断是一级评论还是二级评论(因为都是通过一个文本域提交评论),思路:声明一个全局变量,如果是回复(二级评论)那么会触发点击回复事件,在这个事件的回调函数里给全局变量设置为true ...

  3. jquery click()方法 语法

    jquery click()方法 语法 作用:当点击元素时,会发生 click 事件.当鼠标指针停留在元素上方,然后按下并松开鼠标左键时,就会发生一次 click.click() 方法触发 click ...

  4. 如何安装 Angular CLI 并且检查 CLI 的版本

    想在系统中安装 Angular CLI ,如何进行安装并且如何检查 CLI 的版本? 可以使用命令: npm install -g @angular/cli 进行安装. 使用命令 ng version ...

  5. es6字符串的扩展——模板

    todo1.模板字符串 传统的 JavaScript 语言,输出模板通常是这样写的(下面使用了 jQuery 的方法). $('#result').append( 'There are <b&g ...

  6. MySQ彻底删除与安装配置

    彻底删除 1.查看 MySQL 安装了哪些东西 rpm -qa |grep -i mysql 2.卸载 -.el7.x86_64 -.el7.x86_64 .noarch -.el7.x86_64 - ...

  7. sqli-labs(38)

    0X01 ?id=' and 1=1%23 正确 ?id=1' and 1=2%23 错误 存在注入 0x1 堆叠注入讲解 (1)前言 国内有的称为堆查询注入,也有称之为堆叠注入.个人认为称之为堆叠注 ...

  8. [CSP-S模拟测试]:迷宫(最短路)

    题目传送门(内部题123) 输入格式 输入文件的第一行为四个正整数$n,m,k,d$. 接下来$m$行,每行三个整数$u,v,w$,描述一条无向道路. 输入文件最后一行包含$k$个整数,为$p_0,p ...

  9. 分布式-网络通信-IO-基础(2)

    IS 与 OS1. 基本 IO 操作1.1. InputStream 与 OutputStream1.1.1. 输入与输出我们编写的程序除了自身会定义一些数据信息外,经常还会引用外界的数据,或是将自身 ...

  10. 对于Java培训出身的同学,接下来该怎么学习技术?

    首先恭喜从培训班出来找到工作的同学,确实挺不容易的,4个月的培训,每天从早上9点到晚上9点,也是996,主要的活动地方就是宿舍和教室, 让我现在也去培训,我估计还熬不下来. 尤其是对于从小白开始的同学 ...