可以看看这个博客写得还有总结的都很好传送门
ac代码:
#include<iostream> #include<algorithm> #include<map> #include<cstring> using namespace std; typedef long long ll; const int mod=1e9+7; const int maxn=2e6+10; ll a[maxn]; ll cnt[119]; int main(){ int t; cin>>t; while(t--){ int n; scanf("%d",&n); memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); for(int j=0;j<=60;j++){ if((a[i]>>j)&1) cnt[j]++; } } ll ans=0; for(int i=1;i<=n;i++){ ll base=1; ll t1=0; ll t2=0; for(int j=0;j<=60;j++){ if((a[i]>>j)&1){ t1=(t1+base*cnt[j]%mod)%mod; t2=(t2+base*n%mod)%mod; } else{ t2=(t2+base*cnt[j]%mod)%mod; } base=(base*2)%mod; } ans=(ans+t1*t2%mod)%mod; } printf("%lld\n",ans); } }
#include<iostream>#include<algorithm>#include<map>#include<cstring>using namespace std;typedef long long ll;const int mod=1e9+7;const int maxn=2e6+10;ll a[maxn];ll cnt[119];int main(){int t;cin>>t;while(t--){int n;scanf("%d",&n);memset(cnt,0,sizeof(cnt));for(int i=1;i<=n;i++){scanf("%lld",&a[i]);for(int j=0;j<=60;j++){if((a[i]>>j)&1) cnt[j]++;} }ll ans=0;for(int i=1;i<=n;i++){ll base=1;ll t1=0;ll t2=0;for(int j=0;j<=60;j++){if((a[i]>>j)&1){t1=(t1+base*cnt[j]%mod)%mod;t2=(t2+base*n%mod)%mod; } else{t2=(t2+base*cnt[j]%mod)%mod;}base=(base*2)%mod; }ans=(ans+t1*t2%mod)%mod;}printf("%lld\n",ans);}}