異或和之和
時間限制: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 ...