[51nod] 1301 集合异或和

考虑不限制xor{Y}>xor{X}

  • 考虑n=m的情况,每个数i∈[1,n]可以被分配到X集合或Y集合,或不分配
  • 设f[S]表示{X} xor {Y} == S的方案数
  • 有f[S]+=2*f[S^i]
  • 考虑n!=m,那就是多余的部分得强制分配,分开两个转移即可

考虑限制xor{Y}>xor{X}

  • 对于数B>A,在二进制表示下,就是B和A的前面相等,直到某一位B为1,A为0,之后无所谓
  • 枚举这一位k,限制B(xor{Y})第k位为1,且B xor A第k位为0(统计答案限制范围)
  • 状态加一维f[S][0/1]表示A xor B==S且B的第k位是0/1
  • 转移分开讨论两个情况
  • 1.放进X集合,直接继承状态
  • 2.放进Y集合,根据i第k位转移
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MOD = 1000000007;
    const int MAXN = 4096;
    int n,m;
    
    long long f[MAXN][2],g[MAXN][2];
    long long ans;
    
    int main(){
        n=rd();m=rd();
        int mx=max(n,m),tmp=mx;
        int len=0;
        while(tmp){len++;tmp>>=1;}
        for(int k=1;k<=len;k++){
            memset(f,0,sizeof(f));
            f[0][0]=1;
            for(int i=1;i<=mx;i++){
                memcpy(g,f,sizeof(f));
                for(int s=mx<<1;s>=0;s--){
                    if(i<=n){
                        f[s][0]+=g[s^i][0];
                        f[s][1]+=g[s^i][1];
                    }
                    if(i<=m){
                        f[s][0]+=g[s^i][(i>>(k-1))&1];
                        f[s][1]+=g[s^i][((i>>(k-1))+1)&1];
                    }
                    f[s][0]%=MOD;f[s][1]%=MOD;
                }
            }
            for(int i=(1<<(k-1));i<(1<<k);i++){
                ans+=f[i][1];
            }
            ans%=MOD;
        }
        cout<<ans;
        return 0;
    }

     

转载于:https://www.cnblogs.com/ghostcai/p/9606214.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值