hdu4810 <Cn中取i异或和>

本文介绍了一种使用组合数学解决特定问题的方法——给定一组整数,求所有可能的子集中,选取固定数量元素进行异或操作后的总和。通过将整数分解为二进制形式并利用组合数计算每比特位对结果的贡献,实现了高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:
     给你n个数,让你输出n个数,没一次输出的是在这n个数里面取i个数异或的和(所有情况<C n中取i>)。

思路:
     首先把所有的数都拆成二进制,然后把他们在某一位上的数字加起来,比如        3 = 11  5 = 101 他俩合并就是 112 就这样吧所有的数都合并了,一共最多32位,然后我们考虑,对于每一位,只有选择奇数个1的时候才会是1,否则就是0 ,所以我们可以一次枚举每一位,比如当前要取6个数,对于第三位有8个1,那么当前的这位就是
     C[8][1] * C[N-8][6-1] * 2^3 
  + C[8][3] * C[N-8][6-3] * 2^3 
  + C[8][5] * C[N-8][6-5] * 2^3

其中变化的那个1 3 5 就是去奇数的情况,每一次取完奇数后乘以剩下的的(6 - 奇数)的情况就是一共有多上中取当前奇数的情况 然后在乘以对应位上产生的数 2^3加在一起就是当要求取6个的时候在第三位上的8个1能产生的价值。

#include<stdio.h>
#include<string.h>

#define N 1005

__int64 C[N][N];
__int64 A[40] ,B[40];
__int64 mod = 1000003;

void DB_C()
{
   C[0][0] = C[1][0] = C[1][1] = B[1] = 1;
   for(int i = 2 ;i <= 35 ;i ++)
   B[i] = B[i-1] * 2 % mod;
   for(int i = 2 ;i <= 1002 ;i ++)
   {
      C[i][0] = 1;
      for(int j = 1 ;j <= i ;j ++)
      C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
   }
   return ;
}

int main ()
{
   int n ,i ,j ,k ,num;
   DB_C();
   while(~scanf("%d" ,&n))
   {
      memset(A ,0 ,sizeof(A));
      for(i = 1 ;i <= n ;i ++)
      {
         scanf("%d" ,&num);
         int tt = 0;
         while(num)
         {
            A[++tt] += (num&1);
            num /= 2;
         }
      }
      for(i = 1 ;i <= n ;i ++)
      {
         __int64 ans = 0;
         for(j = 1 ;j <= 32 ;j ++)
         {
            for(k = 1 ;k <= A[j] && k <= i ;k += 2)
            {
               if(i - k > n - A[j]) continue;
               __int64 tmp = C[A[j]][k] * C[n - A[j]][i - k] % mod;
               ans = (ans + tmp * B[j]) % mod;
            }
         }
         if(i == 1) printf("%I64d" ,ans);
         else printf(" %I64d" ,ans);
      }
      printf("\n");
   }
   return 0;
}
               
      
      
   



在CUDA编程中,kernel<<<>>>是用来启动并行计算的语法。在<<<>>>中,必须指定一个表达式作为参数,该表达式指定了并行计算的线程块(block)线程(thread)的数量。这个表达式的格式可以是一个常数,也可以是一个变量或者一个计算表达式。 例如,如果想要启动一个有16个线程块256个线程的并行计算,可以使用以下形式的表达式: kernel<<<16, 256>>>(); 其中,16表示线程块的数量,256表示每个线程块中的线程数量。 另外,如果希望在编译时指定默认的线程块线程数量,可以使用宏定义或者模板的方式来实现。通过设置默认值,并在调用kernel时不指定表达式,就可以使用默认的线程块线程数量。同时,也可以添加依赖关系来根据不同的条件设置不同的默认值。 总结起来,当使用kernel<<<>>>时,必须提供一个表达式来指定线程块线程的数量。这个表达式可以是一个常数、变量或者计算表达式。另外,也可以通过设置默认值添加依赖关系来实现更灵活的使用方式。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [玩转CUDA——提示应输入表达式](https://blog.youkuaiyun.com/gaohang_hdu/article/details/81119627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Kconfig语法](https://download.youkuaiyun.com/download/pengfei24/4328218)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值