異或和之和

2021-10-10 12:25:25 字數 1620 閱讀 2348

異或和之和

時間限制:c/c++ 1秒,其他語言2秒

空間限制:c/c++ 262144k,其他語言524288k

64bit io format: %lld

題目描述

給乙個陣列,陣列內有 個正整數。

求這些數任取3個數異或運算後求和的值。

有幾個個三元組,計算這些三元組內部異或,之後求和。(具體操作可以見樣例描述)

由於該值可能過大,輸出其對 取模的值。

輸入描述:

輸出描述:

任取三個數、三元組內部位異或後求和對取模的值。

示例1輸入複製4

3 4 5 6

輸出複製

10說明

共有4個三元組:、、、

相加為。

**這題異或和,遇到這種題我們暴力肯定不行的,我們想像像異或,按位與,按位或等等都是按照每一位進行處理的。這一題我們也可以對每一位進行處理,將每一位上的1統計起來,2^18最多64位。

只有1才是有值的,為1的情況就是

1xor1xor1

1xor0xor0

這兩種情況

那麼我們就是要求組合數了,比如說總共6個數,第3位1的個數有4個。

那麼所有的組合就是c(4,3)+c(6-4,2)*4;

那麼組合數怎麼求吶。

我們知道按照公式就是n!/m!(n-m)!

因為資料過大,我們要對其進行取餘操作,眾所周知,取餘加法,乘法,減法都適合,唯獨減法不可以。

那麼我們怎麼辦吶,有大佬就想出來逆元這個概念,將除法變成乘法就可以進行取餘了。

逆元怎麼求的,讀者可以自行查閱一下下。

具體解釋看**

**

#include

using

namespace std;

#define ld long double

typedef

long

long ll;

const ll p=

1e9+7;

int vs[65]

;ll quick_pow

(ll a,ll b)

//快速冪

a=a*a%p;

b>>=1;

}return res;

}ll inv

(ll a)

//a的逆元,在p位質數的情況下才有,詳細情況應該是費馬小定理推出的,不過擴充套件歐幾里得好像也可以求

ll zuheshu

(ll a,ll b)

return res;

}int

main()

k++;s>>=1;

}}ll res=0;

for(

int i=

0;i<=

64;i++

) cout<}

知識點:位運算

思路:做這一類題有個技巧,就是每一位分別去處理,1e18對應二進位制的64位。

可以先統計出每一位的1的個數和0的個數,那麼異或和就可以用組合數學的方式求出來了,因為異或為1一定是:

11 xorxor 11 xorxor 11

或者11 xorxor 00 xorxor 00

這兩種情況中的一種,分別處理即可。(別忘了對應位最後乘以 2^i )

異或和之和 異或問題

題目 有n個數,任選3個進行異或,求出所有三元組的異或和的和 普通計算是 o n 3 但是發現,對於異或的運算,就轉換為二進位制的運算,把每乙個陣列轉換為二進位制,再拆分,當且僅當 1 1 1 和 1 0 0 時,答案才為1,否則都是0,也就是說,只有這兩個情況是由貢獻的 把每個數位化為二進位制,然...

異或和之和 組合數學

傳送門 思路 考慮每位對答案的貢獻,因為最大為2 182 218,所以最大一共64位。儲存每乙個1的個數,貢獻產生只能出現兩種情況 p os 1 pos1 pos1 乙個1,兩個0.p os 2 pos2 pos2 三個1。然後用組合數和加法原理對貢獻求和即可。即第i ii位的貢獻ans i c a...

P3908 異或之和

求1 bigoplus 2 bigoplus cdots bigoplus n1 2 n 的值。a bigoplus ba b 即aa bb 按位異或。輸入格式 1 個整數nn。輸出格式 1 個整數,表示所求的值。輸入樣例 1 3 輸出樣例 1 0 對於50 的資料,1 le n le 10 61 ...