題目大意
給出兩個數,構造一個升序序列,使得按照題意所述方式構造的也是升序,問構造方案數對取模後的值。
分析過程
這道題目需要先嚐試構造出前幾個,然後可以發現一個結論是對於構造出來的,都有的二進制數對應的最高位比的二進制數對應的最高位的位置要高。有可這個結論之後,我們就可以按照二進制數位的最高位來將整數分組,即這樣一直劃分下去。在構造答案時,每一次可以在每一組中選擇一個數字或者不選,最後根據計數的乘法原理可算出最終方案數,注意要減去每一組都沒有選的情況(即爲),然後再注意一下最後一個分組和的大小關係判斷即可,此處應該取。
AC代碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll m, d;
void solve(){
ll ans = 1, i = 1;
while((1 << (i - 1)) - 1 <= d){
ll temp = min(d, (ll)(1 << i) - 1) - ((1 << (i - 1)) - 1);
ans = ans * (temp + 1) % m;
++i;
}
cout<<(ans - 1 + m) % m<<'\n'; //減去全不選的情況
}
int main(){
int t, i, j;
ios::sync_with_stdio(false);
cin>>t;
while(t--){
cin>>d>>m;
solve();
}
return 0;
}