codeforces 1330D: Dreamoon Likes Sequences(组合数学+规律)

题意

给一个d,m,让你构造一个数组a大小为n,n不定,a满足严格递增,且元素范围[1,n]
并且a的前缀异或也要严格递增。

思路

首先看二进制每一位上,因为是异或,所以如果a[i]的二进制第j位有1,那么a[i+1]必须如果最高位1是第j位是肯定不行的。
即: ( 1 ) ( 2 , 3 ) ( 4 , 5 , 6 , 7 ) ( 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ) (1) (2,3) (4,5,6,7) (8,9,10,11,12,13,14,15) 每组括号里面的元素不能同时选。
所以对于d等于5
( 1 ) ( 2 , 3 ) ( 4 , 5 ) (1) (2,3) (4,5)
第一个括号有2种方案,不选+选1
第二个括号有3个方案,不选+选2+选3
第三个括号有3个方案,不选+选4+选5
但这种计数把空集也算进去了,所以最后答案要减去1.

code

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
#define IOS ios::sync_with_stdio(0)
typedef long long ll;
const ll mod = 1e9+7;

int main() {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
    int t;
    cin >> t;
    while(t--){
        ll n,k;
        cin >> n >> k;
        ll sum = 1;
        int i;
        for(i = 1;n>=(1<<i);i++){
            ll cnt = (1<<(i-1));
            sum = sum * ((cnt + 1)% k) % k;
        }
        sum = sum * ((n - (1ll<<(i-1)) + 2)% k )% k;
        sum = (sum - 1 + k )% k; 
        cout << sum << endl;
    }
    return 0;
}
原创文章 93 获赞 12 访问量 8996

猜你喜欢

转载自blog.csdn.net/weixin_43571920/article/details/105372244