其他分享
首页 > 其他分享> > CF1557C(组合数,位运算)

CF1557C(组合数,位运算)

作者:互联网

CF1557C(组合数,位运算)

题意

给出序列长度 \(n\) ,取值范围 \([0,2^k - 1]\) 。

求满足 \(a_1 \& a_2 \& a_3 ... \& a_n \ge a_1 \oplus a_2 \oplus ... \oplus a_n\) 的方案数。

思路

先分奇偶讨论。

当 \(n\) 为奇数时,只可能使得不等式等号成立。大于号总不可能成立。因此考虑取等方案。对某一位,操作后都为0或1。

则对任意一个二进制位有: \((C_n^0+C_n^2+C_n^4+...+C_n^{n-1})+C_n^n = 2^{n-1}+1\)

当 \(n\) 为偶数时,如果使得等号成立。操作后二进制位都为0。

则对任意一个二进制位有:\((C_n^0+C_n^2+C_n^4+...+C_n^{n})-C_n^n=2^{n-1}-1\)。

考虑使得大于号成立条件。

我们可以将结果二进制为分为三类。分别是最高位与操作为1的位置 \(i\) , \([0,i-1]\) 和 \([i+1,k-1]\)。

\(i\) 位上一定全1,总方案为1。\([0,i-1]\) 全 \(0\) ,用求等号时公式可算,\([i+1,k-1]\) 任意。

则对第 \(i\) 位有:\((2^{n-1}-1)^i*(2^n)^{k-i-1}\) 。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<stack>
#include<string>
#include<random>
#include<iomanip>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define int long long
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
using namespace std;
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x;}
typedef pair<int,int> PII;
const int MAXN =10 + 2e5 ,mod=1e9 + 7;
int ksm(int a,int b) {
    int ans = 1;
    while(b) {
        if(b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
void solve()
{    
    int n,k; cin >> n >> k;
    ll ans = 0;
    // 1111  X0000YYY
    // X: 0000 C()
    // n % 2 == 0
    // 11111   X00000Y
    // X :0 Y :0/1  C(n,2k) (0~n) 2k != n
    // [0,k] i[i-1,0] C(i-1,j) * pow(pow(2,n)),i - j)
    // A = B  C(n,2k) 
    ans = ksm(ksm(2,n - 1) + ((n & 1) ? 1 : -1),k);
    if(n % 2 == 0) {// [0,k - 1]
        // [0,i-1]: 0 [i] :1 [i+1,k - 1]:0/1
        rep(i,0,k - 1) {
            ans = (ans + ksm(ksm(2,n - 1) - 1,i) * ksm(ksm(2,n),k - i - 1) % mod) % mod;
        }
    }
    cout << ans << endl;
    
}
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}

标签:CF1557C,运算,组合,int,long,ans,ksm,include,define
来源: https://www.cnblogs.com/Mxrush/p/16426435.html