starletkiss 2020-04-17
这道题的关键是有两个限制,1个是递增,1个是异或
那么如果我们要求递增,则i和i-1的最高位不能相同,因为这样bi就被异或导致失去最高位
因此我们知道最高位相同的数是冲突的,所以我们求取最高位为i的个数是多少个
我们发现答案是 2i----2^(i+1)-1这个区间内的数都可以,那么取值就是取值就是相减+1,另外,我们也可以不选最高位为i的数。
之后就是组合了,再每组中选一个,或者不选。但是最后要注意的是,全部都不选是不行的。
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<string> #include<vector> using namespace std; typedef long long ll; ll mod(ll a,ll b){ return (a%b+b)%b; } int main(){ int t; cin>>t; while(t--){ ll n,m; cin>>n>>m; ll ans=1; ll s=1; int i; for(i=0;i<=30;i++){ if((1<<i)>n) break; ans=(ans*(min(n,(1ll<<i+1)-1)-(1<<i)+2))%m; } ans--; cout<<mod(ans,m)<<endl; } return 0; }