给定 x,mx,mx,m,求有多少 yyy 满足 y∈[1,m],x≠yy \in [1,m],x \neq yy∈[1,m],x=y 且 x⊕yx \oplus yx⊕y 是 xxx 或 yyy 的因子。
结论猜测:x⊕y∈[1,x)x \oplus y \in [1,x)x⊕y∈[1,x),下面是证明:
对于一个 ppp 的因子 fff,满足 f≤⌊p2⌋f \le \lfloor \frac{p}{2} \rfloorf≤⌊2p⌋,也就是说 fff 和 ppp 在二进制下的最高位不同。
当 y≥2xy \ge 2xy≥2x 时,x⊕yx \oplus yx⊕y 与 yyy 在二进制下的最高位相同,所以 x⊕yx \oplus yx⊕y 在此时必定不是 yyy 的因子。同时,由于最高位的不同,此时 x⊕y>xx \oplus y > xx⊕y>x 一定成立,所以 x⊕yx \oplus yx⊕y 同样也不是 xxx 的因子。
所以说,只有 y<2xy < 2xy<2x 时,才能满足题意,也就是说因子 x⊕y<xx \oplus y < xx⊕y<x。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define init(x) memset (x,0,sizeof (x))
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX = 1e5 + 5;
const int MOD = 1e9 + 7;
inline ll read ();
ll t;
int main ()
{
//freopen (".in","r",stdin);
//freopen (".out","w",stdout);
t = read ();
while (t--)
{
ll x = read (),m = read ();
ll cnt = 0;
for (int i = 1;i <= x;++i)
{
ll y = x ^ i;
if (!(1 <= y && y <= m)) continue;
if (x % (x ^ y) == 0 || y % (x ^ y) == 0) ++cnt;
}
printf ("%lld\n",cnt);
}
return 0;
}
inline ll read ()
{
ll s = 0;int f = 1;
char ch = getchar ();
while ((ch < '0' || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}

被折叠的 条评论
为什么被折叠?



