题意:

     给你一个串数字,然后让你在这里面挑取两个集合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. 剑指 Offer 32 - I. 从上到下打印二叉树 + 层次遍历二叉树

    剑指 Offer 32 - I. 从上到下打印二叉树 Offer_32_1 题目描述 解题思路 这题属于简单题,考察的是我们对二叉树以及层次遍历的方法. 这里只需要使用简单的队列即可完成二叉树的层次遍 ...

  2. 剑指 Offer 59 - II. 队列的最大值--滑动窗口的建模+Deque的基本使用(常用方法)

    剑指 Offer 59 - II. 队列的最大值 题目链接 package com.walegarrett; /** * @Author WaleGarrett * @Date 2020/12/3 1 ...

  3. 链表算法题之中等级别,debug调试更简单

    文章简述 大家好,本篇是个人的第 5 篇文章 从本篇文章开始,分享关于链表的题目为中等难度,本次共有 3 道题目. 一,两数相加 1.1 题目分析 题中写到数字是按照逆序的方式存储,从进位的角度看,两 ...

  4. 因MemoryCache闹了个笑话

    前言 是这么一回事: 我正在苦思一个业务逻辑,捋着我还剩不多的秀发,一时陷入冥想中...... 突然聊天图标一顿猛闪,打开一看,有同事语音: 大概意思是:同事把项目中Redis部分缓存换成Memory ...

  5. 一文搞懂 this、apply、call、bind

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14506269.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  6. Typora的一些快捷键

      语法格式 快捷键 标题 # + 空格 = 一级标题, ## + 空格 =二级标题, 以此类推 shift + 数字1 =一级标题 ,shift + 数字2 =二级标题 , 以此类推 有序列表 1 ...

  7. VS2008开发WinCE程序编译速度慢的解决办法

    1.找到以下文件 C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets 2.用记事本打开该 ...

  8. 手把手教你docker安装宝塔面板

    手把手教你docker安装宝塔面板(针对小白提一下:需要先安装docker,安装docker的教程请自行百度,非常简单的),docker安装宝塔面板教程如下: 一.拉取centos镜像(当然这里拉取别 ...

  9. 10 分钟轻松学会 Jackson 反序列化自动适配子类

    作者:丁仪 来源:https://chengxuzhixin.com/blog/post/Jackson-fan-xu-lie-hua-zi-dong-shi-pei-zi-lei.html json ...

  10. C++单重继承分析

    code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...