专栏文章

[ARC208C] Mod of XOR 题解

AT_arc208_c题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minl1tkp
此快照首次捕获于
2025/12/02 04:09
3 个月前
此快照最后确认于
2025/12/02 04:09
3 个月前
查看原文
我尽量讲得易懂一点。
首先很显然,xCx\oplus C 是可能的一个解,我们可以提前 check。
有位运算,有取模,这很难转换,于是我们尝试从“异或之后的结果与原数的关系”下手。
我们开始分类讨论。
第一种:nn 最高位大于等于 CC 最高位。
这时候你发现 nCn\oplus C 一定小于 2n2n。如果 nC<nn\oplus C<n,那么 n=xCn=x\oplus C 就是可能的解;否则我们可以把 (nC)modn(n\oplus C)\bmod n 变成 (nC)n(n\oplus C)-n,然后我们再把 nCnn\oplus C-n 变成 n+C2(n and C))nn+C-2(n \text{ and }C))-nC2(n and C)C-2(n \text{ and }C)。因此我们可以得到 n and C=Cx2n\ \text{and}\ C=\frac{C-x}{2}。这个时候,如果 C<xC<x 或者 CxC-x 为奇数或者 Cx2\frac{C-x}{2} 不是 CC 的二进制子集,nn 就无解。
否则,为了确保 nn 最高位大于等于 CC 最高位,我们可以构造 n=Cx2+2Wn=\frac{C-x}{2}+2^W。这里 WW 取到 3030 以上应该都行,我取到了 5050
接下来我们讨论 nn 最高位低于 CC 最高位。
这时候你发现 nCn\oplus C 一定大于等于 2n2n,有什么用吗?好像没用。
似乎没有进展了。我们换一种方向思考:我们能不能根据上面讨论出来的无解情况,继续尝试构造有解情况?
首先是 C<xC<x。显然 n<Cn<C,所以 (nC)modn(n\oplus C)\bmod n 必定比 nn 小,所以当 C<xC<x 时必定无解。
好像没什么思路了……唉,我们能不能暴力算同余方程?
为什么上面没有想到呢?因为上面的性质太直接了,导致我们直接错过了往同余去想的情况。但是没关系,因为上面的推导在这时候会发挥一些作用的。
我们列出式子:(nC)modn=x(n\oplus C)\bmod n=x
然后根据上面的想法,把 nCn\oplus C 拆掉:(n+C2(n and C))modn=x(n+C-2(n \text{ and }C))\bmod n=x
nn 去掉:(C2(n and C))modn=x(C-2(n \text{ and }C))\bmod n=x
移项:(n and C)modn=Cx2(n \text{ and }C)\bmod n=\frac{C-x}{2}
C<xC<x 我们已经判断掉了。
你发现它还是需要满足上面的关系:CxC-x 是奇数,Cx2\frac{C-x}{2}CC 的二进制子集。
所以 nn 最高位小于 CC 最高位的构造并不能“根据上面分类讨论出来的无解情况,构造有解情况”。
所以只需尝试构造 n=xCn=x\oplus Cn=Cx2+2Wn=\frac{C-x}{2}+2^W
注意构造 xCx\oplus C 的优先级高于我们所判断的一切。
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
const int N=1000010;
int x,c;
bool chk(int n){if(!n)return false;return (n^c)%n==x;}
void solve(){
	cin>>c>>x;
	if(chk(c^x)){
		cout<<(c^x)<<"\n";
		return;
	}
	if(c<x){
		cout<<"-1\n";
		return;
	}
	int d=(c-x)/2;
	if(chk((1ll<<50)+(d&c))){//这里没有判断子集关系等关系,因为如果满足就一定合法,不满足也不影响它无解。
		cout<<(1ll<<50)+(d&c)<<"\n";
		return;
	}
	cout<<"-1\n";
    return;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
    int Tc=1;
    cin>>Tc;
    while(Tc--)solve();
	return 0;
}
/*

*/

评论

0 条评论,欢迎与作者交流。

正在加载评论...