Live2d Test Env

Gym - 101848D:XOR(线性基 欧拉降幂)

题意:给定N,K,P,表示现在有一个集合{0, 1, ..., 2n - 1},问有多少个非空子集的异或和为K; 答案%P。1 ≤ n ≤ 1018, 0 ≤ k ≤ min(2n - 1, 1018), 2 ≤ p ≤ 109, p is prime.)

思路:先抽离出一个线性基出来,然后非基部分乱选,然后基来调整。 而这里显然可以把二进制表示法下只有一个1的那些数抽离出来当基。

所以答案=2^(2^N-N)%P;  要注意的是:

    1,K=0的时候有空集,所以减去。

    2,欧拉降幂的时候2和P要互质,和当P=2时不满足,所以需要特判。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
int qpow(ll a,ll x,int Mod)
{
    int res=1; while(x){
        if(x&1LL) res=1LL*res*a%Mod;
        a=1LL*a*a%Mod; x>>=1LL;
    } return res;
}
int main()
{
    ll N,K,P,res=0;
    scanf("%lld%lld%lld",&N,&K,&P);
    if(P==2) {
        if(K==0) puts("1");
        else puts("0");
        return 0;
    }
    res=qpow(2,((qpow(2,N,P-1)-N%(P-1))%(P-1)+P-1)%(P-1),P)-(K==0);
    res=(res%P+P)%P;
    printf("%lld\n",res);
    return 0;
}

 

posted @ 2019-09-05 10:22  nimphy  阅读(504)  评论(0编辑  收藏  举报