「题解」简单题

真就简单题

「我的做题历程」:

step1:观察题面。
  「若 t = 1 t = 1 t=1,则接下来有两个数 L , R L,R L,R,表示区间 [ L , R ] [L, R] [L,R] 的每个数均反转;若 t = 2 t = 2 t=2 ,则接下来只有一个数 i i i,表示询问的下标。」 ,这……这不就是区间修改单点查询嘛。(靓仔无语中)


step2:思考解法。
  第一种解法:起初,我想 0 / 1 0/1 0/1 反转应该是等价于奇偶性转换的,即偶数代表 0 0 0,奇数代表 1 1 1(譬如 2 2 2 是偶数,代表 0 0 0 3 3 3 是奇数,代表 1 1 1)。因为奇数加奇数等于偶数,偶数加奇数等于奇数,所以可以得出任意一个数加上奇数,它的奇偶性就会发生变化(偶变奇,奇变偶)。刚好符合此处 0 / 1 0/1 0/1 反转的要求。于是,我们可以正常的做树状数组的区间修改单点查询,其增量为 1,单点查询时输出该数模 2 2 2 即为答案。(不知道树状数组的同学这边请 → 树状数组)
  第二种解法:后来听评讲,发现了另一种高级做法——异或(异或,写作 ⊕ \oplus ,代码表示为 ^,意为将两个整数作为二进制数,对二进制表示中的每一位逐一运算,当且只当只有两个对应位不同时才为 1 1 1)。异或运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变。而且异或符合交换律,即 a ⊕ b ⊕ c = a ⊕ c ⊕ b a \oplus b \oplus c = a \oplus c \oplus b abc=acb。我们可以利用异或的这些性质对树状数组进行处理,通过两次异或实现与区间修改,通过异或和实现单点查询。

step3:完成代码。
  顺便说一下,虽然此题看似数据不大,但实际不写快读过不了(OJ 应该能过,柠檬上不行)。

代码(抵制学术不端行为,拒绝 Ctrl + C):
// 解法一
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5; 
int n, m, op, l, r, xi, BIT[N];
int lowbit(int x) { return x & -x; }
void update(int x, int k) {
	for (int i = x; i <= n; i += lowbit(i)) {
		BIT[i] += k; 
	}
	return;
}
int sum(int x) {
	int ans = 0;
	for (int i = x; i >= 1; i -= lowbit(i)) {
		ans += BIT[i]; 
	}
	return ans;
}
int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') {
			f = -1;
		}
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + ch - '0';
		ch = getchar();
	}
	return x * f;
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d", &op);
		if (op == 1) {
			l = read(), r = read();
			update(l, 1);
			update(r + 1, -1); 
		} else {
			scanf("%d", &xi);
			printf("%d\n", sum(xi) % 2); // 奇偶性代表 0/1
		}
	} 
	return 0;
}

// 解法二
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5; 
int n, m, op, l, r, xi, BIT[N];
int lowbit(int x) { return x & -x; }
void update(int x, int k) {
	for (int i = x; i <= n; i += lowbit(i)) {
		BIT[i] ^= k; 
	}
	return;
}
int sum(int x) {
	int ans = 0;
	for (int i = x; i >= 1; i -= lowbit(i)) {
		ans ^= BIT[i]; 
	}
	return ans;
}
int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') {
			f = -1;
		}
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + ch - '0';
		ch = getchar();
	}
	return x * f;
}
int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d", &op);
		if (op == 1) {
			l = read(), r = read();
			update(l, 1);
			update(r + 1, 1); 
		} else {
			scanf("%d", &xi);
			printf("%d\n", sum(xi));
		}
	} 
	return 0;
}


(简单的 Accepted ne……)


让我们来解决 『简单题』 叭~

Bye bye!!1 👋👋

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值