二分乱搞过题 || solution - CF2039C2
Solution
设
显然暴力枚举是不行的,那这个
通过写了一个暴力,我们发现满足条件的
然后就这样二分乱搞过了。
Code
#include<iostream>
#include<cstdio>
#include<bitset>
#define int long long
#define il inline
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rpe(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
int x,m;
il int gm(int x)
{
int ans=0;
while(x) ++ans,x>>=1;
return (1ll<<ans)-1;
}
il bool check(int mid)
{
return (x^mid)<=m;
}
il void solve(int __Ti)
{
cin>>x>>m;
if(m<=x*2)
{
int cnt=0;
rep(i,1,m) ((x^i)%x==0 || (x^i)%i==0) && (++cnt,1);
return cout<<cnt<<'\n',void();
}
int t=gm(x);
int cnt=0;
rep(i,1,t) ((x^i)%x==0 || (x^i)%i==0) && (++cnt,1);
int l=1,r=m/x+100,mid=-1;
while(l<r)
{
mid=l+r+1>>1;
check(x*mid) ? (l=mid) : (r=mid-1);
}
cnt+=l-1;
rpe(i,l,max(l-10,1ll)) !check(x*i) && (--cnt,1);
rep(i,l+1,l+10) check(x*i) && (++cnt,1);
cout<<cnt<<'\n';
}
signed main()
{
ios::sync_with_stdio(0); ios_base::sync_with_stdio(0); cin.tie(nullptr); cout.tie(nullptr);
int __T; cin>>__T; rep(__Ti,1,__T) solve(__Ti);
return 0;
}