codeforces D. Dreamoon Likes Sequences

在这里插入图片描述

题目

题意:

给你一个 d , m d,m ,问你满足 b i = b i 1 a i b_i=b_{i-1} \bigoplus a_i b i > b i 1 b_i>b_{i-1} 中的 a a 序列有几种。

思路:

因为要满足 b i = b i 1 a i b_i=b_{i-1} \bigoplus a_i b i > b i 1 b_i>b_{i-1} ,这说明了 b i b_i 的最高位肯定要高于 a i a_i 的最高位 v v 的,所以可以得出式子 x [ m i n ( 2 v , d ) , 2 v + 1 ] x\in [min(2^v, d), 2^{v+1}] 因为这样的话, b b 这样岔开的话,由于异或的关系, b i b_i 一定比 b i 1 b_{i-1} 高一位。所以满足条件,所以可以得出在这个 i i a i a_i 可以选择的可能有 c n t i = 2 v + 1 m i n ( 2 v , d ) + 1 + 1 cnt_i = 2^{v+1} - min(2^v, d) + 1 + 1 (后一个 1 1 表示这个位可以不选),所以总数是 c n t 1 c n t 2 . . . . . c n t n 1 cnt_1*cnt_2 * .....cnt_n - 1 (最后一个 1 -1 是由于如果全算进去的话,会有一种全不选的可能,所以要减一)。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <set>
#include <map>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
typedef vector<int> veci;
typedef vector<ll> vecl;
typedef pair<int, int> pii;
template <class T>
inline void read(T &ret) {
    char c;
    int sgn;
    if (c = getchar(), c == EOF) return ;
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    sgn = (c == '-') ? -1:1;
    ret = (c == '-') ? 0:(c - '0');
    while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
    ret *= sgn;
    return ;
}
inline void out(ll x) {
    if (x > 9) out(x / 10);
    putchar(x % 10 + '0');
}
const int maxn = 50;
int sum[maxn] = {0};
int main() {
    int t, m, d;
    read(t);
    while (t--) {
        read(d), read(m);
        fill(sum, sum + maxn, 1);
        for (int i = 0; i < 31; i++) {
            if (d < (1 << i)) break;
            sum[i] = (min((1 << (i + 1)) - 1, d) - (1 << i) + 2) % m;
        }
        ll ans = 1;
        for (int i = 0; i < 31; i++) {
            ans = (1ll * sum[i] * ans) % m;
        }
        ans = (ans + m - 1) % m;
        printf("%lld\n", ans);
    }
    return 0;
}

发布了463 篇原创文章 · 获赞 27 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_45031646/article/details/105386532