hdu4810 Cn中取i异或和
生活随笔
收集整理的這篇文章主要介紹了
hdu4810 Cn中取i异或和
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ?給你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
? ? ?給你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; }
總結
以上是生活随笔為你收集整理的hdu4810 Cn中取i异或和的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu4829 带权并查集(题目不错)
- 下一篇: hdu 3062 基础的2sat