题意:

     给你一个串数字,然后让你在这里面挑取两个集合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;

}



  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. #define MOD (1000000000 + 7)

  5. __int64 sum_xor[1002][2050] ,now_xor[1002][2050];
  6. __int64 sum_and[1002][2050] ,now_and[1002][2050];
  7. __int64 num[1002];
  8. int main ()
  9. {
  10. int i ,j ,n ,t;
  11. scanf("%d" ,&t);
  12. while(t--)
  13. {
  14. scanf("%d" ,&n);
  15. for(i = 1 ;i <= n ;i ++)
  16. scanf("%I64d" ,&num[i]);
  17. memset(sum_xor ,0 ,sizeof(sum_xor));
  18. memset(now_xor ,0 ,sizeof(now_xor));
  19. for(i = 1 ;i <= n ;i ++)
  20. {
  21. sum_xor[i][num[i]] ++;
  22. now_xor[i][num[i]] ++;
  23. for(j = 0 ;j <= 2048 ;j ++)
  24. if(sum_xor[i-1][j])
  25. {
  26. now_xor[i][j^num[i]] += sum_xor[i-1][j];
  27. sum_xor[i][j^num[i]] += sum_xor[i-1][j];
  28. sum_xor[i][j] += sum_xor[i-1][j];
  29. now_xor[i][j^num[i]] %= MOD;
  30. sum_xor[i][j^num[i]] %= MOD;
  31. sum_xor[i][j] %= MOD;
  32. }
  33. }
  34. memset(sum_and ,0 ,sizeof(sum_and));
  35. memset(now_and ,0 ,sizeof(now_and));
  36. for(i = n ;i >= 1 ;i --)
  37. {
  38. sum_and[i][num[i]] ++;
  39. now_and[i][num[i]] ++;
  40. for(j = 0 ;j <= 2048 ;j ++)
  41. if(sum_and[i+1][j])
  42. {
  43. now_and[i][j&num[i]] += sum_and[i+1][j];
  44. sum_and[i][j&num[i]] += sum_and[i+1][j];
  45. sum_and[i][j] += sum_and[i+1][j];
  46. now_and[i][j&num[i]] %= MOD;
  47. sum_and[i][j&num[i]] %= MOD;
  48. sum_and[i][j] %= MOD;
  49. }
  50. }
  51. __int64 ans = 0;
  52. for(i = 2 ;i <= n ;i ++)
  53. {
  54. for(j = 0 ;j <= 2048 ;j ++)
  55. if(sum_xor[i-1][j] && now_and[i][j])
  56. ans = (ans + sum_xor[i-1][j] * now_and[i][j]) % MOD;
  57. }
  58. printf("%I64d\n" ,ans);
  59. }
  60. return 0;
  61. }


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. 追洞小组 | 实战CVE-2020-7471漏洞

    出品|MS08067实验室(www.ms08067.com) 本文作者:守拙(Ms08067实验室追洞小组成员) 一.漏洞名称: 通过StringAgg(分隔符)的潜在SQL注入漏洞 二.漏洞编号: ...

  2. 从Android手机的抢红包插件说起

    前语 最近,Android手机上的手机管家更新了新版本,提供了红包闹钟功能,只要有微信红包或者QQ红包,就会自动提醒.恰逢最近又在做UI自动化的工作,使用到UI Automator框架.几行代码,就可 ...

  3. java基础详解-集合

    一.集合组成 java集合主要由Map和Collection组成,Collection主要类图如下(图片来源于网络,懒得画图): 从上图中能很明显的看出来Collection下主要是Set.List和 ...

  4. go语言几个最快最好运用最广的web框架比较

    比较一下常用的golang web框架 令人敬畏的Web框架 如果你为自己设计一个小应用程序,你可能不需要一个Web框架,但如果你正在进行生产,那么你肯定需要一个,一个好的应用程序. 虽然您认为自己拥 ...

  5. 使用shell脚本替换Hadoop配置文件的值

    因为懒汉式的实现是线程安全的,所以会降低整个访问速度,而且每次访问都要判断一次.有没有更好的方式实现呢?可以使用"双重检查枷锁"的方式来实现. 所谓"双重检查加锁&quo ...

  6. 通过unity Distribution Portal发布华为渠道的游戏

    背景说明 前面几个帖子详细介绍了: Unity Editor安装和Apk打包 手把手教您快速运行Unity提供的华为游戏demo 使用unity完成华为游戏的初始化和华为帐号登录 快速开发Unity游 ...

  7. Java 8 Stream API 详解

    Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (b ...

  8. Angle Beats Gym - 102361A

    题目链接:https://vjudge.net/problem/Gym-102361A 题意:给定N个点,q次询问每次询问给一个点,问在N个点中取2个和给定点最多可以组成几个直角三角形. 思路:htt ...

  9. 《逆向工程核心原理》——DLL注入与卸载

    利用CreateRemoteThread #include <iostream> #include <tchar.h> #include <Windows.h> # ...

  10. 12、MyBatis教程之缓存

    13.缓存 简介 1.什么是缓存 [ Cache ]? 存在内存中的临时数据. 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高 ...