牛客練習賽60 A 大吉大利 簽到 位運算

2021-10-04 12:33:34 字數 1701 閱讀 6444

題目鏈結(click)

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

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

64bit io format: %lld

題目描述

給定n個整數,依次為a1,a2,…,an。

求∑ i=

1n∑j

=1n(

ai&a

j)

\sum_^n\sum_^n(a_i\&a_j)

i=1∑n​

j=1∑

n​(a

i​&a

j​)'&'是二進位制與運算子。

輸入描述

第一行乙個整數n.

第二行n個整數ai.

輸出描述
乙個整數表示上述求和式的答案.

樣例輸入
5

1 2 3 4 5

樣例輸出
備註
1≤ n ≤1e5

0≤ ai ≤1e8

分析

先瞄一眼所求和式,明面上o(n2)的時間複雜度。

再看一眼資料範圍:1≤ n ≤1e5,心如死灰。

當然,acmer早已見怪不怪,縱使題目虐我千百遍,我仍待她如初戀。

咱們先好好觀察一下這「初戀」,和式中心的』&'也許是突破口,眾所周知,位運算往往用來優化時間、空間複雜度,出題人也許在這藏了什麼貓膩。

真·分析

正所謂,好記憶體不如爛硬碟 ,咳咳,我們先在紙上模擬一下這個和式。

先就 i==1 來看:

a1&a1+a1&a2+a1&a3+…+a1&an

即a1和每一項分別相與(&)再相加(+)

既然&是按位與,那麼我們就從位的角度來看,分析每一位如何變化:

假如a1的某一位是0,那麼無論相與物件的該位是什麼,相與結果皆為0,對結果無貢獻。

假如a1的某一位是1,同理,只有當相與物件該位為1時,結果才為1,貢獻為1*(該位權重)

不僅是a1,對於每乙個ai均是如此,假設特定位為第k位,所有ai該位上共有m個1

則,該位對答案的貢獻為:m*m*(1<<(k-1))

如此,只要預處理出每一位上1的個數即可,複雜度o(n)

「talk is cheap. show me the code.」

#include

#include

#include

using

namespace std;

const

int maxn =

1e5+5;

typedef

long

long ll;

int num[maxn]

;int b[31]

;//由於非負,第32位必位0

intmain

(void

)for

(int i =

0; i <

31; i++

)//貢獻彙總

ans +

=(ll)b[i]

* b[i]*(

1ll<< i)

;printf

("%lld\n"

, ans)

;return0;

}

牛客練習賽60 A 大吉大利 思維

傳送門 a 大吉大利.題目描述 給定n個整數,依次為a1 a2 an。求 i 1n j 1n ai a j sum n sum n a i a j i 1n j 1 n a i a j 是二進位制的與運算子。輸入描述 第一行乙個整數n.第二行nn個整數 ai.輸出描述 乙個整數表示上述求和式的答案....

牛客練習賽60 A 大吉大利(位運算)

給定 n nn 個整數,依次為 a1,a2,a na 1,a 2,a n a1 a2 an 求 i 1 n j 1n a i aj sum n sum n a i a j i 1n j 1 n a i a j katex parse error expected eof got at positio...

牛客練習賽60補題

思路 考慮位運算 的特性 只有兩者都為1才會對答案有貢獻 且 對答案貢獻的值為 1 k 其中k是當前1所在二進位制下的位數 所以考慮預處理每乙個位的1出現的次數 其中對每一位都會遍歷n n次 所以每一位對答案的貢獻就是 a i a i 1 i a i 為當前位置1的個數 include using ...