题目:
Dreamoon likes sequences very much. So he created a problem about the sequence that you can't find in OEIS:
You are given two integers d,m find the number of arrays a, satisfying the following constraints:
- The length of a is n, n≥1
- 1≤a1<a2<⋯<an≤d
- Define an array b of length n as follows: b1=a1, ∀i>1,bi=bi−1⊕ai, where ⊕ is the bitwise exclusive-or (xor). After constructing an array b, the constraint b1<b2<⋯<bn−1<bn should hold.
Since the number of possible arrays may be too large, you need to find the answer modulo m.
思路:容易想到如果两个数二进制的最高位都是1,则两者"^"后者数值一定比前者小,可以推断出"2^0 ~ 2^1 - 1","2^1 ~ 2^2 - 1",...,"2^(n-1) ~ 2^(n) - 1"为不同集合,我们只需要统计出每个集合的个数,然后求出组合方案数就行。
1 #include<iostream> 2 #include<string> 3 #include<vector> 4 #include<cstdio> 5 6 #define ll long long 7 #define pb push_back 8 9 using namespace std; 10 11 const int N = 1e6 + 10; 12 vector<ll > a; 13 ll p[N]; 14 ll ans, MOD; 15 16 void init() 17 { 18 int x = 0; 19 while(1){ 20 p[x] = (1 << x) - 1; 21 if(p[x] > 1e9) break; 22 x++; 23 } 24 } 25 26 27 void solve() 28 { 29 30 init(); 31 32 int T; 33 cin >> T; 34 while(T--){ 35 36 ans = 1; 37 a.clear(); 38 39 ll n; 40 cin >> n >> MOD; 41 42 int inx = -1; 43 for(int i = 1; i < 32; ++i){ 44 if(n >= p[i]) a.pb(p[i] - p[i - 1]); 45 else{ 46 inx = i; 47 break; 48 } 49 } 50 51 if(n - p[inx - 1] > 0) a.pb(n - p[inx - 1]); 52 for(auto x : a){ 53 ans = (ans * (x + 1)) % MOD; 54 } 55 56 ans = (ans - 1 + MOD) % MOD; 57 58 //cout << "(ans = " << ans << ")" << endl; 59 cout << ans << endl; 60 } 61 } 62 63 int main() { 64 65 ios::sync_with_stdio(false); 66 cin.tie(0); 67 cout.tie(0); 68 solve(); 69 //cout << "ok" << endl; 70 return 0; 71 }