首页 技术 正文
技术 2022年11月9日
0 收藏 615 点赞 3,138 浏览 2251 个字

题意:

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


相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,488
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,736
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,487
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,127
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,289