「PEOI Rd1」异或(xor)
2026-09-18 21:26:20
发布于:湖北
P9223 「PEOI Rd1」异或(xor)题解
题意简述
给定两个正整数 ,求以下式子的值:
其中 表示按位异或运算。
数据范围:。
题目分析
由于 and 高达 ,直接双重循环枚举 and 的时间复杂度为 ,显然会超时。我们需要利用异或运算的性质,将问题分解为二进制每一位独立计算。
按位贡献法
异或运算是按位独立的。对于任意整数 ,其二进制表示为 ,其中 。
因此, 的值可以表示为:
其中 和 分别表示 and 在二进制第 位上的值(0 或 1)。
我们将求和公式展开并交换求和顺序:
这意味着,我们可以单独计算每一位 对最终答案的贡献。第 位的贡献为 ,其中 是所有数对 中,满足 的对数。
注意:
-
中间做乘法时,乘积最高可达 ,long long 是不够用的,可以选择高精度或者用 __int128 进行中间乘法运算的载体
-
一定要记得取模哦
AC代码
#include<iostream>
using namespace std;
using ll=long long;
using int1=__int128;
ll aaa(ll N,ll k) {
if (N <= 0){
return 0;
}
ll x1=1LL<<(k+1),x2 = 1LL<<k;
ll x3=N/x1;
ll cnt=x3 *x2;
ll r=N%x1;
if(r>=x2) {
cnt+=r-x2+1;
}
return cnt;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int a;
cin>>a;
while(a--) {
long long n,m;
cin >> n >> m;
long long ans = 0;
for (ll k=0;k<60;k++) {
int1 a1=aaa(n,k);
int1 b1=n-a1;
int1 a2=aaa(m,k);
int1 b2=m-a2;
int1 p1=a1*b2;
int1 p2=b1*a2;
int1 t=p1+p2;
int1 m=t % 998244353;
ll p = (1LL << k) % 998244353;
int1 c=(m*p)%998244353;
ans=(ans+c)%998244353;
}
cout << ans << endl;
}
return 0;
}
全部评论 6
- 置顶
现在可以加精吗
2026-09-18 来自 湖北
0全站推荐了
2天前 来自 湖北
0
秒杀拆贡献题是人?秒杀拆贡献题是人?秒杀拆贡献题是人?秒杀拆贡献题是人?
2026-09-18 来自 广东
0什么意思啊?
2026-09-18 来自 湖北
0
洛谷提交这篇题解能过吗?
2026-09-11 来自 湖北
0你太强了我提交了快10篇都没过
2026-09-11 来自 浙江
0我也没过
2026-09-11 来自 湖北
0
ACGO上无原题
2026-09-11 来自 湖北
0我太区了,只配做黄题
2026-09-11 来自 湖北
0黄题无法加精
2026-09-11 来自 湖北
0
可以加精吗,@Unknown_Error@cjdst@AC君
2026-09-11 来自 湖北
0比我强,不加精

2026-09-11 来自 广东
0o(╥﹏╥)o
2026-09-11 来自 湖北
0欺负小朋友
2026-09-11 来自 湖北
0




















有帮助,赞一个