题面

原题题面

转化方便版题意:

n

n

n 堆石子,第

i

i

i 堆有

c

i

[

1

,

m

]

c_i\in [1,m]

ci​∈[1,m] 个石子,有

q

q

q 次询问,每次询问给出

L

i

,

R

i

L_i,R_i

Li​,Ri​ ,先把

c

i

∉

[

L

i

,

R

i

]

c_i\not\in [L_i,R_i]

ci​​∈[Li​,Ri​] 的石堆都扔掉,然后把每堆石子减少

L

i

L_i

Li​ 个,最后用剩下的若干堆石子做

N

i

m

Nim

Nim 游戏,先手必胜输出

A

\tt A

A ,后手必胜输出

B

\tt B

B 。

1

n

,

m

,

q

2

1

0

5

1\leq n,m,q\leq2\cdot10^5

1≤n,m,q≤2⋅105.

题解

官方题解,是

O

(

N

N

log

N

)

O(N\sqrt{N\log N})

O(NNlogN

​) 的做法。

对每个询问暴力求解,是

O

(

N

2

)

O(N^2)

O(N2) 的。或者,如果记录每一种

c

i

c_i

ci​ 值的出现次数的话,也可以是

O

(

N

M

)

O(NM)

O(NM) 的。后者可以优化:

c

i

c_i

ci​ 的二进制表示有

18

\tt18

18 位,我们把前面九位和后面九位分开算,这样,分别就只有

2

9

=

512

2^9=512

29=512 种取值,也就是

M

\sqrt{M}

M

​ 种取值了,这就增加了暴力的可能性。同时,只管前九位和后九位都是能比较方便地处理加减法的,因此这样刚好是可行的,要是分成前六位、中六位、后六位就及其不好做了。

但是,处理后九位数字还是比较麻烦的。而且,这个时间复杂度也不优。

不如看看下面又易懂又好写还在时间复杂度上暴踩官解的做法。


真是妙蛙种子吃着妙脆角,妙进了米奇妙妙屋,妙到家了

真的就不能每一位分开来做了吗?

加减法固然会对二进制表示产生不好计量的影响,但是我们有这么一条很容易发现的结论:

  • A

    <

    2

    k

    A<2^k

    A<2k ,则

    A

    +

    2

    k

    =

    A

    x

    o

    r

    2

    k

    A+2^k=A~xor~2^k

    A+2k=A xor 2k

这种情况下,加法是等同于异或的!

那我们不妨就想个办法,能不能把减法变成加法,然后把要加的部分按位拆分开来,利用上面的结论一步一步异或进去呢?

有!那就是倍增。倍增可以把减法换成加法,而且不难发现,倍增刚好是从高位往低位考虑的,前面要加的数的 lowbit 一定比后面的数都大。

我们定义

f

[

i

]

[

j

]

f[i][j]

f[i][j] 为询问

L

=

i

,

R

=

i

+

2

j

1

L=i,R=i+2^j-1

L=i,R=i+2j−1 时的答案,不难发现

f

[

i

]

[

0

]

=

0

f[i][0]=0

f[i][0]=0。

计算

f

[

i

]

[

j

]

f[i][j]

f[i][j] 的时候,先异或上

f

[

i

]

[

j

1

]

f[i][j-1]

f[i][j−1] ,然后由于

f

[

i

+

2

j

1

]

[

j

1

]

f[i+2^{j-1}][j-1]

f[i+2j−1][j−1] 中的每堆石子个数

<

2

j

1

< 2^{j-1}

<2j−1 ,我们把这些石堆加上

2

j

1

2^{j-1}

2j−1 时,等价于异或

2

j

1

2^{j-1}

2j−1,因此我们只需要再知道

[

i

+

2

j

1

,

i

+

2

j

1

]

[i+2^{j-1},i+2^j-1]

[i+2j−1,i+2j−1] 区间之内石堆的个数,就可以转移了。令

c

t

[

i

]

[

j

]

ct[i][j]

ct[i][j] 表示

c

i

[

i

,

i

+

2

j

1

]

c_i\in[i,i+2^j-1]

ci​∈[i,i+2j−1] 的石堆的个数,则:

f

[

i

]

[

j

]

=

f

[

i

]

[

j

1

]

x

o

r

f

[

i

+

2

j

1

]

[

j

1

]

x

o

r

(

2

j

1

(

c

t

[

i

+

2

j

1

]

[

j

1

]

%

2

)

)

c

t

[

i

]

[

j

]

=

c

t

[

i

]

[

j

1

]

+

c

t

[

i

+

2

j

1

]

[

j

1

]

f[i][j]=f[i][j-1]~{\tt xor}~f[i+2^{j-1}][j-1]~{\tt xor}~\Big( 2^{j-1}\cdot(ct[i+2^{j-1}][j-1]\,\%\,2) \Big)\\ ct[i][j]=ct[i][j-1]+ct[i+2^{j-1}][j-1]

f[i][j]=f[i][j−1] xor f[i+2j−1][j−1] xor (2j−1⋅(ct[i+2j−1][j−1]%2))ct[i][j]=ct[i][j−1]+ct[i+2j−1][j−1]

询问的时候,类似的。由于是倍增,每次访问到的

f

[

i

]

[

j

]

f[i][j]

f[i][j] 的

j

j

j 都会变小,也就是说它所代表的这个区间内的石堆

c

i

c_i

ci​ 都小于先前的

2

j

2^j

2j ,都可以把加法换成异或,再通过

c

t

[

i

]

[

j

]

ct[i][j]

ct[i][j] 补到

f

[

i

]

[

j

]

f[i][j]

f[i][j] 中。

代码也很好理解,基本是标准的预处理倍增。时间复杂度只有

O

(

N

log

N

)

O(N\log N)

O(NlogN) 。

CODE

比解说还短的倍增代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 200005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
int n,m,i,j,s,o,k;
int c[MAXN],dp[MAXN][20],ct[MAXN][20];
int main() {
// Input
n = read();m = read();
for(int i = 1;i <= n;i ++)
c[i] = read(),ct[c[i]][0] ++; // Init
for(int i = m;i > 0;i --) {
for(int j = 1;i+(1<<j)-1 <= m;j ++) {
ct[i][j] = ct[i][j-1] + ct[i+(1<<(j-1))][j-1];
dp[i][j] = dp[i][j-1] ^ dp[i+(1<<(j-1))][j-1] ^ ((ct[i+(1<<(j-1))][j-1] & 1) ? (1<<(j-1)):0);
}
} // Query
int q = read();
while(q --) {
s = read();o = read();
int xr = 0,as = 0;
for(int j = 18;j >= 0;j --) {
if(s+(1<<j)-1 <= o) {
as ^= dp[s][j]^((ct[s][j] & 1) ? xr:0);
xr ^= (1<<j); s += (1<<j);
}
}
printf(as ? "A":"B");
}
return 0;
}

CF1511G Chips on a Board (倍增)的更多相关文章

  1. Codeforces 1511G - Chips on a Board(01trie/倍增)

    Codeforces 题面传送门 & 洛谷题面传送门 一道名副其实的 hot tea 首先显然可以发现这俩人在玩 Nim 游戏,因此对于一个 \(c_i\in[l,r]\) 其 SG 值就是 ...

  2. Architecture of Device I/O Drivers, Device Driver Design

    http://www.kalinskyassociates.com/Wpaper4.html Architecture of Device I/O Drivers Many embedded syst ...

  3. ARM JTAG 信号 RTCK 应该如何处理?

    用户在调试内嵌可综合内核的 CPU 如 ARM7TDMI-S 时,需要通过打开仿真器的自适应时钟功能. 此时,ARM仿真器根据 RTCK 时钟信号的频率,产生可用于 CPU 内核当前时钟主频的最快的 ...

  4. Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors

    Implementation of Serial Wire JTAG flash programming in ARM Cortex M3 Processors The goal of the pro ...

  5. CF1511G-Chips on a Board【倍增】

    正题 题目链接:https://www.luogu.com.cn/problem/CF1511G 题目大意 给出\(n*m\)的棋盘上每一行有一个棋子,双方轮流操作可以把一个棋子向左移动若干步(不能不 ...

  6. Codeforces Round #194 (Div. 2) D. Chips

    D. Chips time limit per test:1 second memory limit per test:256 megabytes input:standard input outpu ...

  7. ACM-ICPC Beijing 2016 Genius ACM(倍增+二分)

    描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数,如果 S 中的整 数不够 M 对,则取到不能取为止),使 ...

  8. CH0601 Genius ACM【倍增】【归并排序】

    0601 Genius ACM 0x00「基本算法」例题 描述 给定一个整数 M,对于任意一个整数集合 S,定义“校验值”如下: 从集合 S 中取出 M 对数(即 2∗M 个数,不能重复使用集合中的数 ...

  9. Codeforces Round #194 (Div. 1) B. Chips 水题

    B. Chips Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/333/problem/B D ...

随机推荐

  1. DirectX11 With Windows SDK--19(Dev) 编译Assimp并加载模型、新的Effects框架

    前言 注意:这一章进行了重写,对应教程Dev分支第19章的项目,在更新完后面的项目后会替换掉原来第19章的教程 在前面的章节中我们一直使用的是由代码生成的几何模型,但现在我们希望能够导入模型设计师生成 ...

  2. Eureka入门

    一个Eureka中分为eureka server和eureka client.其中eureka server是作为服务的注册与发现中心.eureka client既可以作为服务的生产者,又可以作为服务 ...

  3. Acwing 428

    可以找到规律,将第 N 项的 N 对应的二进制表示,转换为以 k 为基底的数即可. N=1=1 ----> 1 ----> \(a^b\) N=2=2 ----> 10 ----&g ...

  4. 架构师必备:系统容量现状checklist

    正如飞机在起飞前,机长.副机长要过一遍checklist检查,确认没问题了才能起飞.楼主也整理了一个系统容量现状checklist,方便对照检查.本文搭配架构师必备:如何做容量预估和调优,食用更佳. ...

  5. SQL server设置连接数

    SQLServer查看及设置最大连接数   很多时候自己本地开发会遇到 ,打开几个连接正常访问 之后就报错误,这时候需要调整sqlserver 最大连接数. 1. 查询最大连接数 SELECT val ...

  6. MySQL-1-概念

    数据库相关概念 DB:数据库(database):存储数据的"仓库".它保存了一系列有组织的数据 DBMS:数据库管理系统,又称为数据库软件(产品),用于管理DB中的数据 SQL: ...

  7. 解开XAML的邪恶面纱

    什么是XAML,首先我们看下它的外观 <Window x:Class="Blend_WPF.WindowStyle"        xmlns="http://sc ...

  8. 有关于weiphp2.00611上传sae的一些注意(图片上传解决方案)

    一.安装中注意的事项  安装时使用的系统为weiphp2.0611    版本     1.将所有文件上传到代码库中     2.按照步骤进行安装weiphp,注意在数据库导入的时候需要手动导入.  ...

  9. python写个前端,这不是轻轻松松~

    前端除了用js++css+html,还有没有其它办法?其实python也可以 1. 安装与基本流程 Python学习交流Q群:660193417### 安装 PyWebIO 和其他的第三方库一样使用p ...

  10. 更强的 JsonPath 兼容性及性能测试之2022版(Snack3,Fastjson2,jayway.jsonpath)

    2022年了,重新做了一份json path的兼容性与性能测试.三个市面上流行框架比较性测试. 免责声明:可能测试得方式不对而造成不科学的结果(另外,机器不同结果会有不同),可以留言指出来.以下测试数 ...