题意:

     给你一个串数字,然后让你在这里面挑取两个集合S ,T,集合的要求是

(1)不能为空

(2)S集合的所有元素必须在T集合的左边

(3)S集合的XOR == T集合的AND

     问可以找到多少组这样的集合对。

思路:

      两种方法,一个是枚举T集合的第一个元素,或者是枚举S集合的最后一个元素,首先我们开四个数组


sum_xor[1002][2050] 记录从左到右直到第i个节点的时候的j这个数字有多少种可能

now_xor[1002][2050] 记录从左到右直到第i个节点并且必须选择i这个节点时j出现的次数

sum_and[1002][2050] 同理.(只不过是n-->1)..

now_and[1002][2050] 同理. (只不过是n-->1)..


更新数组的时候可以想象下01背包,当前的状态由上一步的所有可能状态和当前的这个数字组合出来后得到的新状态,对于sum_..记得加上上一步的所有状态,这个题目关键就是枚举的时候不能出现重复的集合对。然后我们枚举一遍就ok了,两种枚举方法,第一种是sum_xor,now_and两个状态组合,另一

个是now_xor ,sum_and组合,给个关键的代码

for(i = 1 ;i <= n ;i ++)

{

    now_xor[i][num[i]] ++;//自己这个状态

    sum_xor[i][num[i]] ++;//自己这个状态

    for(j = 0 ;j <= 2048 ;j ++)

    {

       if(sum_xor[i-1][j])//如果之前有j这个状态

       {

          now_xor[i][j^num[i]] += sum_xor[i-1][j];//新状态的增加值

          sum_xor[i][j^num[i]] += sum_xor[i-1][j];//新状态的增加值

          sum_xor[i][j] += sum_xor[i-1][j];//当前的和也要加上之前的所有可能和

          //然后都MOD一下

        }  

     }

}


AND的同理...


求出来这4个数组之后的两种枚举方法(两种几乎一样)

(1)枚举T集合的第一个

for(i = 2 ;i <= n ;i ++)

{

   for(j = 0 ;j <= 2048 ;j ++)

   if(sum_xor[i-1][j] && now_and[i][j])

   ans = (sum_xor[i-1][j] * now_and[i][j]) % MOD;

}

(2)枚举S集合的最后一位

for(i = 1 ;i <= n - 1 ;i ++)

{

   for(j = 0 ;j <= 2048 ;j ++)

   if(now_xor[i-1][j] && sum_and[i][j])

   ans = (now_xor[i-1][j] * sum_and[i][j]) % MOD;

}



#include<stdio.h>
#include<string.h> #define MOD (1000000000 + 7)

__int64
sum_xor[1002][2050] ,now_xor[1002][2050];
__int64
sum_and[1002][2050] ,now_and[1002][2050];
__int64
num[1002]; int main ()
{
int
i ,j ,n ,t;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d" ,&n);
for(
i = 1 ;i <= n ;i ++)
scanf("%I64d" ,&num[i]);
memset(sum_xor ,0 ,sizeof(sum_xor));
memset(now_xor ,0 ,sizeof(now_xor));
for(
i = 1 ;i <= n ;i ++)
{

sum_xor[i][num[i]] ++;
now_xor[i][num[i]] ++;
for(
j = 0 ;j <= 2048 ;j ++)
if(
sum_xor[i-1][j])
{

now_xor[i][j^num[i]] += sum_xor[i-1][j];
sum_xor[i][j^num[i]] += sum_xor[i-1][j];
sum_xor[i][j] += sum_xor[i-1][j];
now_xor[i][j^num[i]] %= MOD;
sum_xor[i][j^num[i]] %= MOD;
sum_xor[i][j] %= MOD;
}
}

memset(sum_and ,0 ,sizeof(sum_and));
memset(now_and ,0 ,sizeof(now_and));
for(
i = n ;i >= 1 ;i --)
{

sum_and[i][num[i]] ++;
now_and[i][num[i]] ++;
for(
j = 0 ;j <= 2048 ;j ++)
if(
sum_and[i+1][j])
{

now_and[i][j&num[i]] += sum_and[i+1][j];
sum_and[i][j&num[i]] += sum_and[i+1][j];
sum_and[i][j] += sum_and[i+1][j];
now_and[i][j&num[i]] %= MOD;
sum_and[i][j&num[i]] %= MOD;
sum_and[i][j] %= MOD;
}
}
__int64
ans = 0;
for(
i = 2 ;i <= n ;i ++)
{
for(
j = 0 ;j <= 2048 ;j ++)
if(
sum_xor[i-1][j] && now_and[i][j])
ans = (ans + sum_xor[i-1][j] * now_and[i][j]) % MOD;
}

printf("%I64d\n" ,ans);
}
return
0;
}


hdu4901 枚举状态(找集合对S(xor) ==T(and))的更多相关文章

  1. { MySQL基础数据类型}一 介绍 二 数值类型 三 日期类型 四 字符串类型 五 枚举类型与集合类型

    MySQL基础数据类型 阅读目录 一 介绍 二 数值类型 三 日期类型 四 字符串类型 五 枚举类型与集合类型 一 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己 ...

  2. 1315E Double Elimination DP 01枚举状态和倍增思想

    E. Double Elimination DP 01枚举状态和倍增思想 题意 参考DOTA2双败赛制,一共有\(2^n\)个队打n轮 其中你有k喜欢的队伍,由你掌控比赛的输赢请问比赛中包含你喜欢的队 ...

  3. 6-12 varchar和char 枚举类型enum 集合set

    1       字符类型char和varchar #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的参 ...

  4. Mysql数据类型《三》枚举类型与集合类型

    枚举类型与集合类型 字段的值只能在给定范围中选择,如单选框,多选框 enum 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female set 多选 在给定的范围内可以选择一个或一 ...

  5. mysql枚举类型与集合类型

    枚举类型与集合类型 字段的值只能在给定范围中选择,如单选框,多选框 enum 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female set 多选 在给定的范围内可以选择一个或一 ...

  6. 【POJ 2411】【Mondriaans Dream】 状压dp+dfs枚举状态

    题意: 给你一个高为h,宽为w的矩阵,你需要用1*2或者2*1的矩阵填充它 问你能有多少种填充方式 题解: 如果一个1*2的矩形横着放,那么两个位置都用二进制1来表示,如果是竖着放,那么会对下一层造成 ...

  7. Delphi基本类型--枚举 子界 集合 数组

    [plain] view plain copy <strong>根据枚举定义集合 </strong> TMyColor = (mcBlue, mcRed); TMyColorS ...

  8. Http状态码集合

    忘了之前在哪里收集的了,先表示感谢. 状态码 含义 100 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请 ...

  9. HDU 5025Saving Tang Monk BFS + 二进制枚举状态

    3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间. 第二次WA,是因为没有枚举蛇的状态. 解体思路: 因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可. 然后多次BFS, ...

随机推荐

  1. 什么原因才是阻碍Linux桌面发展的罪魁祸首

    我大概2000年上大学在宿舍开始玩Linux,到现在20年了!也算是最早一批痴迷于Linux桌面用户啦!记得当时的毕业设计BBS论坛开发就是在Mandrake Linux(后改名Mandriva,一种 ...

  2. 【pytest官方文档】解读fixtures - 8. yield和addfinalizer的区别(填坑)

    在上一章中,文末留下了一个坑待填补,疑问是这样的: 目前从官方文档中看到的是 We have to be careful though, because pytest will run that fi ...

  3. WPF 基础 - Binding 的源与路径

    1. 源与路径 把控件作为 binding 源与 binding 标记拓展: 控制 Binding 的方向及数据更新: Binding 的路径 Path: 没有路径的 Binding: 为 Bindi ...

  4. Servlet原理解析&使用指南

    Servlet(Server Applet)全称Java Servlet,是用Java编写的服务器端程序.广义上指任何实现了Server接口的类,主要功能在于交互式地浏览和生成数据,生成动态Web内容 ...

  5. Hadoop企业开发场景案例,虚拟机服务器调优

    Hadoop企业开发场景案例 1 案例需求 ​ (1)需求:从1G数据中,统计每个单词出现次数.服务器3台,每台配置4G内存,4核CPU,4线程. ​ (2)需求分析: ​ 1G/128m = 8个M ...

  6. 在Python中创建M x N的数组

    在Python中创建M x N的数组 一般有三种方法: 列表乘法 dp = [[0] * n] * m for 循环 dp= [[0 for _ in range(n)] for _ in range ...

  7. 时间同步chrony,最全最细

    时间同步服务 多主机协作工作时,各个主机的时间同步很重要,时间不一致会造成很多重要应用的故障,如:加密协 议,日志,集群等, 利用NTP(Network Time Protocol) 协议使网络中的各 ...

  8. x86汇编 条件跳转

    条件跳转表 汇编语言-条件跳转指令 直接转移指令 指令格式 机器码 测试标志 条件说明 符号  JO       OPR 70  OF=1  结果有溢出    JNO      OPR 71  OF= ...

  9. C语言变量及其生命周期

    变量类型以及作用域和生命周期 变量的作用域 变量的作用域就该变量可以被访问的区间,变量的作用域可以分为以下四种: 进程作用域(全局):在当前进程的任何一个位置都可以访问 函数作用域:当流程转移到函数后 ...

  10. springboot的yml中的bruid没有提示

    解决方案: springboot的yml中的bruid没有提示只要在maven加上:druid-spring-boot-starter(注意版本的统一,否则可能会冲突) 效果图: