题解 CF2225D Exceptional Segments
前言
才发现CF题也能写题解。
分析
给定两个整数
前缀异或和的性质
定义前缀异或和
通过观察前缀异或和的规律,发现其具有周期性,周期为
- 当
i \equiv 0 \pmod 4 时,pre[i] = i ; - 当
i \equiv 1 \pmod 4 时,pre[i] = 1 ; - 当
i \equiv 2 \pmod 4 时,pre[i] = i + 1 ; - 当
i \equiv 3 \pmod 4 时,pre[i] = 0 。
此外,
关键
由于前缀异或和的周期性,只有两种情况可能存在多个
-
pre[i] = 0$:对应 $i = 0 \ / \ i \equiv 3 \pmod 4 -
pre[i] = 1$:对应 $i \equiv 1 \pmod 4
其他情况下,
统计方法
我们需要统计以下四个量:
其中:
代码实现
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 998244353;
ll f(ll a) {
if (a >= 0) {
return a / 4;
} else {
return (a - 3) / 4;
}
}
int main() {
int t;
cin >> t;
while (t--) {
ll n, x;
cin >> n >> x;
ll cnta1 = f(x - 2) + 1, cnta0 = f(x - 4) + 1;
ll cntb1 = f(n - 1) - f(x - 2), cntb0 = f(n - 0) - f(x - 4);
ll ans = (((cnta1 % mod) * (cntb1 % mod)) % mod + ((cnta0 % mod) * (cntb0 % mod)) % mod) % mod;
ans = (ans + (cntb0 % mod)) % mod;
if (ans < 0) {
ans += mod;
}
cout << ans << endl;
}
return 0;
}