专栏文章
题解:AT_abc150_f [ABC150F] Xor Shift
AT_abc150_f题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miob10gd
- 此快照首次捕获于
- 2025/12/02 16:16 3 个月前
- 此快照最后确认于
- 2025/12/02 16:16 3 个月前
题目大意
将 序列前 个数放到最后,使得 ,求满足条件的所有 和 。
思路
首先有一个显然的 暴力,走不下去,考虑其他做法。
异或运算是基于二进制位的,所以往二进制的方向考虑,即要保证所有 的每一个二进制位相等。
记 为 在二进制下 的系数,由于 ,。
即要么 与 均相等,此时 。
要么 与 均不等,此时 。
此时就可以枚举 ,将所有 和 哈希,再将所有 哈希滚动对比。
如果有一个二进制位无法满足条件,则此时的 就不满足条件,标记即可,最后没被标记的 就符合条件。
最后由于 均等于 ,计算其中一组 和 的异或值即可。
代码
CPP#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned ll
const int N = 200050, base = 131; // 本题没有卡自然溢出哈希
int n;
int a[N], b[N], ans[N];
ull p[N] = {1}, h, H, ha[N];
int main() {
cin >> n;
for(int i = 1; i <= n; i ++)
p[i] = p[i - 1] * base;
for(int i = 1; i <= n; i ++)
cin >> a[i];
for(int i = 1; i <= n; i ++)
cin >> b[i];
for(int u = 0; u <= 29; u ++){
int mask = 1 << u;
h = H = 0;
// 将 S_{b_i,u} 和 S_{b_i,u} ^ 1 哈希
for(int i = 1; i <= n; i ++){
h = h * base + !!(b[i] & mask);
H = H * base + !(b[i] & mask);
}
// 将 S_{a_i,u} 哈希
for(int i = 1; i <= n; i ++)
ha[i] = ha[i - 1] * base + !!(a[i] & mask);
for(int i = 0; i < n; i ++)
if((ha[n] - ha[i] * p[n - i]) * p[i] + ha[i] != h && (ha[n] - ha[i] * p[n - i]) * p[i] + ha[i] != H)
ans[i] = 1;
}
for(int i = 0; i < n; i ++)
if(ans[i] == 0)
cout << i << " " << (a[n] ^ b[n - i]) << endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...