T2 开平方
要证明“$x$ 能表示为两个平方数之差当且仅当 $x$ 是奇数或4的倍数”,需从以下两方面分析:
1. 充分性(满足条件的数一定能表示为平方差)
奇数:
设 $x = 2k + 1$($k$ 为整数)。取 $y = k + 1$,$z = k$,则:
$y^2 - z^2 = (k + 1)^2 - k^2 = 2k + 1 = x.$
因此,所有奇数均可表示为平方差。
4的倍数:
设 $x = 4k$($k$ 为整数)。取 $y = k + 1$,$z = k - 1$,则:
$y^2 - z^2 = (k + 1)^2 - (k - 1)^2 = 4k = x.$
因此,所有4的倍数均可表示为平方差。
2. 必要性(能表示为平方差的数必为奇数或4的倍数)
平方差公式为 $x = (y - z)(y + z)$,令 $a = y - z$,$b = y + z$,则 $a$ 和 $b$ 需满足:
1. $a$ 和 $b$ 同奇偶性:
因为 $a + b = 2y$ 必须为偶数,所以 $a$ 和 $b$ 同为奇数或同为偶数。
2. $x = a \cdot b$:
若 $a$ 和 $b$ 均为奇数,则 $x$ = 奇数 $\times$ 奇数 = 奇数。
若 $a$ 和 $b$ 均为偶数,设 $a = 2m$,$b = 2n$,则 $x = 4mn$,即 $x$ 为4的倍数。
综上,若 $x$ 可表示为平方差,则 $x$ 必为奇数或4的倍数。
---
结论
充要条件 :$x$ 能表示为两个平方数之差当且仅当 $x$ 是奇数或4的倍数。
code
#include <bits/stdc++.h>
using namespace std;
signed main() {
int L, R;
cin >> L >> R;
// 计算奇数个数
int odd = (R + 1) / 2 - L / 2;
// 计算4的倍数个数
int mul4 = R / 4 - (L - 1) / 4;
cout << odd + mul4;
return 0;
}
T4 异或
ans = 第k位【 x(x<=n)中的1 】* 【 y(y<=m)中的0】 + 【x(x<=n)中的0】 *【 y(y<=m)】中的1 * (1<<k)
```
for (int i = 0; i <= 60; ++i) {//周期规律 000...111
LL x = 1LL << (i + 1LL);//周期的大小
LL y = x>>1; //周期大小的一半
LL c = (n + 1LL)/x; //有多少个完整的周期
LL p = (n + 1LL)%x; //不完整的部分
ua[i] = (c * y % M + max(p - y, 0LL) % M) % M;//完整的周期个数 * 周期的一半 + 不完整的部分 - 周期的一半
ub[i] = (n - ua[i]) % M;
}
```
查看代码
#include<bitsstdc++.h>
#define LL long long
using namespace std;
const int N = 67;
const LL M = 998244353;
int T;
LL n, m, ua[N], ub[N], va[N], vb[N];
int main() {
scanf("%d", &T);
while (T--) {
scanf("%lld%lld", &n, &m);
for (int i = 0; i <= 60; ++i) {//周期规律 000...111
LL x = 1LL << (i + 1LL);//周期的大小
LL y = x>>1; //周期大小的一半
LL c = (n + 1LL)/x; //有多少个完整的周期
LL p = (n + 1LL)%x; //不完整的部分
ua[i] = (c * y % M + max(p - y, 0LL) % M) % M;//完整的周期个数 * 周期的一半 + 不完整的部分 - 周期的一半
ub[i] = (n - ua[i]) % M;
}
for (int i = 0; i <= 60; ++i) {
LL x = 1LL << (i + 1LL);//周期的大小
LL y = x>>1; //周期大小的一半
LL c = (m + 1LL)/x; //有多少个完整的周期
LL p = (m + 1LL)%x; //不完整的部分
va[i] = (c * y % M + max(p - y, 0LL) % M) % M;//完整的周期个数 * 周期的一半 + 不完整的部分 - 周期的一半
vb[i] = (m - va[i]) % M;
}
LL ans = 0;
for (int i = 0; i <= 60; ++i)
(ans += (ua[i] * vb[i] % M + ub[i] * va[i] % M) % M * ((1LL << i) % M)) %= M;
printf("%lld\n", ans);
}
return 0;
}
浙公网安备 33010602011771号