给定 \(n\) 个数 \(m_i\),求 \((x_1,x_2,...,x_n)\) 的个数,使得 \(x_1 \ xor\ x_2\ xor\ ...\ xor\ x_n = k\),且 \(0 \leq x_i \leq m_i\)

Solution

从最高位开始看起,毫无疑问,如果 \(m_i\) 的某一位是 \(0\),那么 \(x_i\) 的这一位只能填 \(0\),所以只有那些 \(m_i\) 最高位是 \(1\) 的才具有选择权。

考虑从最高位数起,哪一位 \(pos\) 开始,存在一个 \(i\) 使得 \(x_i \neq m_i\),很显然这个 \(pos\) 是有范围的,它一定是从最高位开始往下的一段区间,因为如果某一位上,\(m_i\) 这一位的异或和 \(\neq k\) 的这一位,更低的位就可以扔掉了。

假设从第 \(pos\) 位开始,存在一个 \(i\) 使得 \(x_i \neq m_i\),我们需要统计所有满足这个条件的答案,不妨把这个部分的贡献称作第 \(pos\) 位的贡献。

设 \(f[i][j]\) 表示前 \(i\) 个 \(m\) 的当前位是 \(1\) 的数中,选择了 \(j\) 个 \(x\) 的当前位是 \(1\),\(i-j\) 个是 \(0\) 的方案数,那么

\[f[i][j]=f[i-1][j-1]\cdot (x_i \ mod \ 2^{pos} + 1) + f[i-1][j]\cdot 2^{pos}
\]

考虑如何统计第 \(pos\) 位的贡献,假设这位 \(1\) 的个数为 \(cnt\),那么 \(f[cnt][j]\) 答案的贡献是 \(f[cnt][j]/2^{pos}\),当 \(j\) 与 \(k\) 该位的奇偶性相同时产生。

#include <bits/stdc++.h>
using namespace std; #define int long long
const int N = 105;
const int mod = 1e9+7;
inline void exgcd(int a,int b,int &x,int &y) {
if(!b) {
x=1,y=0;
return;
}
exgcd(b,a%b,x,y);
int t=x;
x=y,y=t-(a/b)*y;
} inline int inv(int a,int b) {
int x,y;
return exgcd(a,b,x,y),(x%b+b)%b;
} int n,k,m[N],f[N][N]; int solve(int pos) {
if(pos<0) return 1; //!
int ret=0,cnt=0;
memset(f,0,sizeof f);
f[0][0]=1;
for(int i=1;i<=n;i++) {
if((m[i]>>pos)&1) {
++cnt;
f[cnt][0]=f[cnt-1][0]*(1<<pos)%mod; //!
for(int j=1;j<=cnt;j++) {
f[cnt][j]=f[cnt-1][j-1]*(m[i]%(1<<pos)+1)
+f[cnt-1][j]*(1<<pos);
f[cnt][j]%=mod;
}
}
else {
for(int j=0;j<=cnt;j++) {
f[cnt][j]=f[cnt][j]*(m[i]+1); //!
f[cnt][j]%=mod;
}
}
}
int r=inv(1<<pos,mod);
for(int j=(k>>pos&1);j<cnt;j+=2) {
ret+=f[cnt][j]*r;
ret%=mod;
}
if((cnt&1) == ((k>>pos)&1)) {
for(int i=1;i<=n;i++) {
if(m[i]>>pos&1) m[i]^=(1<<pos);
}
return (solve(pos-1) + ret)%mod;
}
else return ret;
} signed main() {
ios::sync_with_stdio(false);
while(cin>>n>>k) {
for(int i=1;i<=n;i++) cin>>m[i];
cout<<solve(31)<<endl;
}
}

Wannafly Camp 2020 Day 2B 萨博的方程式 - 数位dp的更多相关文章

  1. Wannafly Camp 2020 Day 3F 社团管理 - 决策单调性dp,整体二分

    有 \(n\) 个数构成的序列 \({a_i}\),要将它划分为 \(k\) 段,定义每一段的权值为这段中 \((i,j) \ s.t. \ i<j,\ a_i=a_j\) 的个数,求一种划分方 ...

  2. Wannafly Winter Camp 2020 Day 5C Self-Adjusting Segment Tree - 区间dp,线段树

    给定 \(m\) 个询问,每个询问是一个区间 \([l,r]\),你需要通过自由地设定每个节点的 \(mid\),设计一种"自适应线段树",使得在这个线段树上跑这 \(m\) 个区 ...

  3. Wannafly Winter Camp 2020 Day 5F Inversion Pairs - 拉格朗日插值,dp

    给定 \(n \leq 10^7\),求所有 \(n\) 的全排列的逆序对个数的 \(k \leq 100\) 次方和 Solution \(f[i][j]\) 表示 \(i\) 个元素,逆序对个数为 ...

  4. Wannafly Camp 2020 Day 3I N门问题 - 概率论,扩展中国剩余定理

    有一个猜奖者和一个主持人,一共有 \(n\) 扇门,只有一扇门后面有奖,主持人事先知道哪扇门后有奖,而猜奖者不知道.每一轮,猜奖者选择它认为的有奖概率最大(如果有多个最大,随机选一个)的一扇门,主持人 ...

  5. Wannafly Camp 2020 Day 3D 求和 - 莫比乌斯反演,整除分块,STL,杜教筛

    杜教筛求 \(\phi(n)\), \[ S(n)=n(n+1)/2-\sum_{d=2}^n S(\frac{n}{d}) \] 答案为 \[ \sum_{d=1}^n \phi(d) h(\fra ...

  6. Wannafly Camp 2020 Day 2D 卡拉巴什的字符串 - 后缀自动机

    动态维护任意两个后缀的lcp集合的mex,支持在串末尾追加字符. Solution 考虑在 SAM 上求两个后缀的 LCP 的过程,无非就是找它们在 fail 树上的 LCA,那么 LCP 长度就是这 ...

  7. Wannafly Camp 2020 Day 1D 生成树 - 矩阵树定理,高斯消元

    给出两幅 \(n(\leq 400)\) 个点的无向图 \(G_1 ,G_2\),对于 \(G_1\) 的每一颗生成树,它的权值定义为有多少条边在 \(G_2\) 中出现.求 \(G_1\) 所有生成 ...

  8. Wannafly Camp 2020 Day 2I 堡堡的宝藏 - 费用流

    感谢这道题告诉我KM求的是 完备 最大权匹配 :( #include <bits/stdc++.h> using namespace std; #define reset(x) memse ...

  9. Wannafly Camp 2020 Day 2J 邦邦的2-SAT模板

    #include <bits/stdc++.h> using namespace std; int main() { int n; cin>>n; cout<<n& ...

随机推荐

  1. [redis读书笔记] 第一部分 数据结构与对象 整数集合

    typedef struct intset { // 编码方式 uint32_t encoding; // 集合包含的元素数量 uint32_t length; // 保存元素的数组 int8_t c ...

  2. sun.misc.Unsafe中一些常用方法记录

    sun.misc.Unsafe中一些常用方法记录 前情摘要 sun公司提供了可以用于直接操作内存的类,这个类就是sun.misc.Unsafe.因为Java本身是不会涉及到直接操作内存的,Java A ...

  3. 一键安装MySQL5.6.43脚本

    [root@lamp ~]# cat /server/scripts/mysql-5.6.43_install.sh #!/bin/bash #卸载系统自带的Mysql /bin/rpm -e $(/ ...

  4. 论文翻译:2018_Artificial Bandwidth Extension with Memory Inclusion using Semi-supervised Stacked Auto-encoders

    论文地址:使用半监督堆栈式自动编码器实现包含记忆的人工带宽扩展 作者:Pramod Bachhav, Massimiliano Todisco and Nicholas Evans 博客作者:凌逆战 ...

  5. .NET Core之单元测试(四):Fluent Assertions的使用

    目录 什么是Fluent Assertions 待测试API 测试用例 什么是Fluent Assertions Fluent Assertions 是 .NET 平台下的一组扩展方法,用于单元测试中 ...

  6. JS循环解决任意日期间的间隔天数

    用JS循环解决任意日期间的间隔天数,并求截止日期是周几 y1=1900 m1=1 d1=1 y2=2000 m2=5 d2=3 days=0 ydays=0 mdays=0 ddays=d2-d1 f ...

  7. Android中点击按钮获取string.xml中内容并弹窗提示

    场景 AndroidStudio跑起来第一个App时新手遇到的那些坑: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103797 ...

  8. MySQL 普通索引和唯一索引的区别

    该文为< MySQL 实战 45 讲>的学习笔记,感谢查看,如有错误,欢迎指正 一.查询和更新上的区别 这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响.建议尽量选择普通索引 ...

  9. idea如何做到多模块开发项目 收藏整理

    idea如何做到多模块开发项目 <packaging>pom</packaging>是什么意思? idea 快捷键汇总

  10. mysql 报错:Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. To disable safe mode, toggle the option in Preferences

    目录 #事故现场 #解决方法 #事故现场 mysql执行update操作报错: sql如下: update psmp.Users set name='Jack' where name='Lily'; ...