Problem

Codechef

Solution

我们可以按位进行考虑,如果一个 \(m_i\) 在某一位上为1,但 \(x_i\) 却取了0,那么我们就称它脱离了限制,更低位可以随便乱填。也就是说,只要高位异或的方案合法,这些更低位,无论其他数怎么填,它都可以使得最终结果合法。

那么这就变成了一个比较方便考虑的计数问题了。可以枚举第一个脱离控制的最高位,然后由于可能有多个数脱离控制,我们就选择最后一个脱离控制的数来进行计数。注意如果这一位没有脱离限制,说明所有这一位有1的都填了1,而如果这种异或方案异或出来的0,1方案与k不相同,那么就是不合法的,及时break掉。

时间复杂度 \(O(n\log v)\)

Code

#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=100010,mod=1e9+9;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
int z,n,k,ans,a[maxn],lim[32],cnt[32][maxn],f[maxn][2],g[maxn];
int pls(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int solve(int x)
{
int res=0;ll tmp,sum;
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
f[0][0]=1;g[n+1]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<2;j++)
{
if(a[i]>>x&1)
{
tmp=lim[x]-(1<<x)+1;
f[i][j]=(f[i][j]+f[i-1][j]*tmp)%mod;
tmp=(a[i]&lim[x])-(1<<x)+1;
f[i][j]=(f[i][j]+f[i-1][j^1]*tmp)%mod;
}
else
{
tmp=(a[i]&lim[x])+1;
f[i][j]=(f[i][j]+f[i-1][j]*tmp)%mod;
}
}
for(int i=n;i;i--)
{
if(a[i]>>x&1) g[i]=(ll)g[i+1]*((a[i]&lim[x])-(1<<x)+1)%mod;
else g[i]=(ll)g[i+1]*((a[i]&lim[x])+1)%mod;
}
for(int i=1;i<=n;i++)
if(a[i]>>x&1)
res=(res+(ll)f[i-1][(k>>x&1)^(cnt[x][i+1]&1)]*g[i+1])%mod;
return res;
}
int main()
{
read(z);
lim[0]=1;
for(int i=1;i<=30;i++) lim[i]=lim[i-1]<<1|1;
while(z--)
{
read(n);ans=k=0;
for(int i=1;i<=n;i++){read(a[i]);k^=a[i];}
for(int j=30;~j;j--) cnt[j][n+1]=0;
for(int i=n;i;i--)
for(int j=30;~j;j--)
cnt[j][i]=cnt[j][i+1]+(a[i]>>j&1);
for(int i=30;~i;i--)
{
ans=pls(ans,solve(i));
if((cnt[i][1]&1)!=(k>>i&1)) break;
ans=pls(ans,(i==0));
}
printf("%d\n",ans);
}
return 0;
}

最新文章

  1. 010商城项目:商品类目的选择——Dao,Service.Action层的分析
  2. Java发送socket请求的工具
  3. OC 相关
  4. 投票系统 &amp; 简易js刷票脚本
  5. jQuery_Ajax_Json 异步接收PHP端传来的json数据
  6. RandomAcessFile、MappedByteBuffer和缓冲读/写文件
  7. AngularJS合集
  8. module_init宏解析
  9. C语言基础05
  10. 关于各种数据库 Insert时同时取到Id的操作
  11. 使用JSR-303进行校验 @Valid
  12. js介绍
  13. 2018-2019-1 20189201《Linux内核原理与分析》第四周作业
  14. Linux 在文件中查找某字符串
  15. 使用quicklz缩小程序体积
  16. HTML第十四章总结 HTML forms
  17. 关于jquery的css的一些知识
  18. windows配置iis网站域名
  19. MVC ---- Linq查询
  20. English trip -- VC(情景课) 6 A Time

热门文章

  1. UVA12538 Version Controlled IDE
  2. excel 技能收集
  3. svmrank 的误差惩罚因子c选择 经验
  4. 【刷题】BZOJ 2594 [Wc2006]水管局长数据加强版
  5. [洛谷P3829][SHOI2012]信用卡凸包
  6. 51nod 1563 坐标轴上的最大团(今日gg模拟第一题) | 线段覆盖 贪心 思维题
  7. BGP的那些安全痛点(转)
  8. 前端学习 -- image标签和meta标签
  9. Android仿iPhone 滚轮控件 实现
  10. Linux下的wine生活(QQ/微信/Office)