题面

原题题面

转化方便版题意:

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. Typora配置阿里云图床

    一.Typora安装PicGo 更新typora到最新版,打开文件-->偏好设置-->图像-->上传服务选择PicGo-Core-->下载或更新   二.注册并配置阿里云 1. ...

  2. 开发工具-在线计算MD5

    更新记录: 2022年6月8日 更新标题. 2022年6月1日 开始. 都记在这以后就不用到处找了. 在线计算MD5 https://www.sojson.com/md5/ http://www.ip ...

  3. 【小程序自动化Minium】一、框架介绍和环境搭建

    微信小程序自动化测试系列分享 一.Minium 简介 minium 是微信团队为小程序专门开发的自动化框架,我们可以用它来做小程序的UI自动化测试,但是它的能力却不仅仅在于UI自动化. 正是得益于官方 ...

  4. 如何从0开发一个Vue组件库并发布到npm

    1.新建文件夹在终端打开执行 npm init -y 生成package.json如下,注意如果要发布到npm,name不能有下划线,大写字母等 { "name": "v ...

  5. UiPath文本操作Get Full Text的介绍和使用

    一.Get Full Text操作的介绍 使用Get Full Text(获取全文本 )屏幕抓取方法从指示的UI元素中提取字符串及其信息 二.Get Full Text在UiPath中的使用 1. 打 ...

  6. nifi从入门到实战(保姆级教程)——flow

    本文章首发于博客园,转载请标明出处 经过前两篇文章(环境篇,身份验证),我们已经有了nifi可以运行的基础,今天就来实现一个案例吧. 假设我们要从ftp上获取一个zip包,里面有两个csv文件,一个是 ...

  7. 模拟HashMap冲突

    最近看HashMap的源码,其中相同下标容易产生hash冲突,但是调试需要发生hash冲突,本文模拟hash冲突. hash冲突原理 HashMap冲突是key首先调用hash()方法: static ...

  8. Tapdata Cloud 版本上新 | 支持通知自配置,支持GP、MQ数据源,界面更友好!

    Tapdata Cloud https://cloud.tapdata.net Tapdata Cloud 是国内首家异构数据库实时同步云平台,目前支持Oracle.MySQL.PG.SQL Serv ...

  9. 通过jmeter压测surging

    前言 surging是异构微服务引擎,提供了模块化RPC请求通道,引擎在RPC服务治理基础之上还提供了各种协议,并且还提供了stage组件,以便针对于网关的访问, 相对于功能,可能大家更想知道能承受多 ...

  10. RabbitMQ消费者消失与 java OOM

    原因: 下午先是收到钉钉告警有一个消费者系统任务积压, 当时以为就是有范围上量没有当回事,后来客服群开始反馈说有客户的数据没有生成.这个时候查看mq的后台,发现任务堆积数量还是很多. 这个时候登录一台 ...