質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

860閲覧

atcoder ABC 147D でWAから抜け出せません。

goro_gnm

総合スコア42

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/01/09 09:26

atcoder の問題を解いているのですが、正解にたどり着けません。
自分で考えてもわからなかったので、私のコードのだめな点を指摘してもらえると助かります。

問題

N 個の整数があり、i 番目の整数は Ai です。
∑(i=1->N-1)∑(j=i+1->N)(Ai XOR Aj) を 10^9+7 で割った余りを求めてください。

整数 A,B のビットごとの排他的論理和 a XOR b は、以下のように定義されます。

  • a XOR b を二進表記した際の 2^k (k≥0) の位の数は、A,B を二進表記した際の 2^k の位の数のうち一方のみが 1 であれば 1、そうでなければ 0 である。

例えば、3 XOR 5=6 となります (二進表記すると: 011 XOR 101=110)。

制約

  • 2≤N≤3×10^5
  • 0≤Ai<2^(60)
  • 入力中のすべての値は整数である。

###自分のコード

c++

1#include<iostream> 2#include<algorithm> 3#include<cmath> 4typedef long long ll; 5using namespace std; 6 7int main(){ 8 int N; cin >> N; 9 ll A[N], ans = 0; 10 int one[60] = {}, count = 0, amari; 11 for(int i=0; i<N; i++) cin >> A[i]; 12 13 // A[i] = 2進数で2^i桁目が1になる数字の数 14 for(int i=0; i<60; i++){ 15 for(int j=0; j<N; j++){ 16 one[i] += A[j]%2; 17 A[j] = A[j]/2; 18 } 19 } 20 for(int i=0; i<60; i++){ 21 if(one[i] == 0) continue; 22 ans += one[i]*(N-one[i])*pow(2, i); 23 ans = ans%1000000007; 24 } 25 cout << ans << endl; 26} 27

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

C++

1 ans += one[i]*(N-one[i])*pow(2, i);

この右辺の最大値は150000 * 150000 * 2^59になるので、long longには乗りません。

投稿2020/01/09 10:13

yudedako67

総合スコア2047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/01/09 15:11

剰余算先にすれば解決すると思いきや起きるであろうバグをもう一つ。 goro_gnmさん前も整数問題でpow使っちゃだーめってお話ししましたよー? 戻り値がdoubleだから2^60もすると整数でも浮動小数点誤差が乗りますって。
goro_gnm

2020/01/10 09:18 編集

yudedako67さん なるほど、最終的な答えの桁数は気にしても途中のことは頭から抜けていました。これはいけませんね。 そこを修正したらACにたどり着くことができました。ありがとうございます。 NotionalKettleさん その節はありがとうございました^^ あれから少し勉強したのですが、2の累乗数はバイナリに変換しても、きれいに表せるから浮動小数点誤差発生しないのでは?と考えました。 だから例外的にpow(2,x)は使ってもいいんじゃないかと。(今冷静に考えたら2^60がそもそもdoubleに入らないから、結局だめかって感じではあるんですが...。) 2の累乗数でも不動小数点誤差は発生するんでしょうか?
退会済みユーザー

退会済みユーザー

2020/01/10 10:25

double(8byte)なら2進数53桁精度らしいので恐らくは2^54で誤差が出始めると思います。 値としては2^60はdoubleに入ると思いますよ? 指数部が11bitで1023引くらしいので仮数部は置いといても2^(2^11-1023)=2^1025は入るみたいです(多分) もちろん整数としての精度はガタガタです
goro_gnm

2020/01/12 14:27

そうなのですね、まだよく理解できていなかったようです。 勉強します>< ありがとうございます。
退会済みユーザー

退会済みユーザー

2020/01/12 14:31

まぁこんなのの具体的な値ってそうそう必要にならないですけどね(誤差が発生しそうなポイントは意識する必要がありますが) 頑張ってください!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問