A
将一个 Fibonacci 数拆成三个 Fibonacci 数。
fi=f0+f0+fi
B
n 个地方,去一个最近的,如果最近的地方不唯一,哪里也不去。
很简单。
C
n 个整数,可以不断任意取两个数,使得一个加一,一个减一,问多可以使得多少数相同。
操作不改变数的总和,如果总和是 n 的倍数,那么答案是 n,否则答案是 n-1。
D
n 杯一样容量,已知果汁浓度( pi )的果汁混合。求混合果汁的浓度。
答案即是 ∑pn 。
E
给出一段文字,将其居中输出。
按照题意模拟即可。
F
查询一个数列的区间和,支持对区间的异或。
考察取每个数第 i 个比特位组成的 0-1 序列,维护区间和只要查询区间的 1 的个数;区间异或时,该位的序列或者不更新(异或 0),或者区间 0-1 翻转(异或 1)。照此发现可以使用线段树维护第 i 位序列的更新和查询,数据值最大有 106 ,使用 20 棵线段树维护每一位即可。
#include <stdio.h>
const int MAX_N = 1e5 + 10;
int a[MAX_N];
struct segment_tree
{
int cnt[MAX_N << 2];
bool flip[MAX_N << 2];
void build(int l, int r, int id, int p)
{
flip[id] = false;
if (l == r) {
cnt[id] = ((a[l] >> p) & 1);
return;
}
int m = (l + r) >> 1;
build(l, m, id << 1, p);
build(m + 1, r, id << 1 | 1, p);
cnt[id] = cnt[id << 1] + cnt[id << 1 | 1];
}
void push_down(int l, int r, int id)
{
if (flip[id] && l != r) {
int m = (l + r) >> 1;
cnt[id << 1] = m - l + 1 - cnt[id << 1];
cnt[id << 1 | 1] = r - m - cnt[id << 1 | 1];
flip[id << 1] ^= 1;
flip[id << 1 | 1] ^= 1;
flip[id] = false;
}
}
void update(int l, int r, int id, int x, int y)
{
push_down(l, r, id);
if (l == x && r == y) {
flip[id] ^= 1;
cnt[id] = r - l + 1 - cnt[id];
return;
}
int m = (l + r) >> 1;
if (y <= m) {
update(l, m, id << 1, x, y);
}
else if (x > m) {
update(m + 1, r, id << 1 | 1, x, y);
}
else {
update(l, m, id << 1, x, m);
update(m + 1, r, id << 1 | 1, m + 1, y);
}
cnt[id] = cnt[id << 1] + cnt[id << 1 | 1];
}
int query(int l, int r, int id, int x, int y)
{
push_down(l, r, id);
if (l == x && r == y) {
return cnt[id];
}
int m = (l + r) >> 1;
if (y <= m) {
return query(l, m, id << 1, x, y);
}
if (x > m) {
return query(m + 1, r, id << 1 | 1, x, y);
}
int ansl = query(l, m, id << 1, x, m);
int ansr = query(m + 1, r, id << 1 | 1, m + 1, y);
return ansl + ansr;
}
};
const int MAX_BIT = 20;
segment_tree sgt[MAX_BIT];
int main()
{
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", a + i);
}
for (int i = 0; i < MAX_BIT; ++i) {
sgt[i].build(1, n, 1, i);
}
int m;
scanf("%d", &m);
for (int i = 1; i <= m; ++i) {
int cmd;
scanf("%d", &cmd);
if (cmd == 1) {
int x, y;
scanf("%d %d", &x, &y);
long long ans = 0;
for (int i = 0; i < MAX_BIT; ++i) {
ans += (long long) (1 << i) * sgt[i].query(1, n, 1, x, y);
}
printf("%lld\n", ans);
}
else {
int x, y, o;
scanf("%d %d %d", &x, &y, &o);
for (int i = 0; i < MAX_BIT; ++i) {
if ((o >> i) & 1) {
sgt[i].update(1, n, 1, x, y);
}
}
}
}
return 0;
}
posted by 张静之