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

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

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

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

Q&A

0回答

361閲覧

bit.sum,bit.add のやっていることを出力して確認したいです。

SmaSTATION

総合スコア29

C++

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

0グッド

0クリップ

投稿2022/11/27 07:04

編集2022/11/29 00:00

前提

下記のプログラムでわからない箇所があるので、挙げさせていただきます。
些細なことでも結構ですので、お答えいただけると幸いです。

問題文:[ここから参照お願いします。](AtCoder ABC 107 D - Median of Medians)

参考にさせていただいたプログラム:ここから参照お願いします。

疑問点(よくわからない箇所)

  • プログラムの60行目、63行目などにある、bit.sum,bit.add の動作がよくわかりません。

文字に置き換えて出力しようとするとエラーになりました。

入力

3
10 30 20

出力

sum=1
geta=4
sum+geta=5
num=1
sum=2
geta=4
sum+geta=6
num=2
sum=3
geta=4
sum+geta=7



sum+geta=6
num=2
sum=3
geta=4
sum+geta=7
num=3
1073741824
×

該当のソースコード

C++

1#include <iostream> 2#include <vector> 3using namespace std; 4 5template <class Abel> struct BIT { 6 const Abel UNITY_SUM = 0; // to be set 7 vector<Abel> dat; 8 9 /* [1, n] */ 10 BIT(int n) : dat(n + 1, UNITY_SUM) { } 11 void init(int n) { dat.assign(n + 1, UNITY_SUM); } 12 13 /* a is 1-indexed */ 14 inline void add(int a, Abel x) { 15 for (int i = a; i < (int)dat.size(); i += i & -i) 16 dat[i] = dat[i] + x; 17 } 18 19 /* [1, a], a is 1-indexed */ 20 inline Abel sum(int a) { 21 Abel res = UNITY_SUM; 22 for (int i = a; i > 0; i -= i & -i) 23 res = res + dat[i]; 24 return res; 25 } 26 27 /* [a, b), a and b are 1-indexed */ 28 inline Abel sum(int a, int b) { 29 return sum(b - 1) - sum(a - 1); 30 } 31 32 /* debug */ 33 void print() { 34 for (int i = 1; i < (int)dat.size(); ++i) cout << sum(i, i + 1) << ","; 35 cout << endl; 36 } 37}; 38 39int main() { 40 long long N; cin >> N; 41 vector<int> a(N); for (int i = 0; i < N; ++i) cin >> a[i]; 42 int low = 0, high = 1<<30; 43 const int geta = N+1; 44 while (high - low > 1) { 45 /*cout << "high=" << high << endl; 46 cout << "low=" << low << endl;*/ 47 int mid = (low + high) / 2; 48 //cout << "mid=" << mid << endl; 49 long long num = 0; 50 BIT<long long> bit(N*2+10); 51 int sum = 0; 52 //cout << "sum+geta=" << sum+geta << endl; 53 bit.add(sum+geta, 1); 54 for (int i = 0; i < N; ++i) { 55 int val; 56 if (a[i] <= mid) val = 1; else val = -1; 57 sum += val; 58 cout << "sum=" << sum << endl; 59 cout << "geta=" << geta << endl; 60 cout << "sum+geta=" << sum+geta << endl; 61 num += bit.sum(1, sum+geta); 62 cout << "num=" << num << endl; 63 //a=bit.add(sum+geta, 1); 64 //cout << "bit.add=" << a << endl; 65 } 66 if (num > (N+1)*N/2/2) high = mid; 67 else low = mid; 68 } 69 cout << high << endl; 70}

試したこと

  • 変数をそれぞれ出力
  • bit.sumとかの出力を試してみる→*をつけてもエラー

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

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

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

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

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

actorbug

2022/11/27 07:44 編集

そもそも、このコードは何をするものなのでしょうか。競プロなら問題も載せてください。 あと、BIT(Binary Indexed Tree)については既にご存じですか。
actorbug

2022/11/27 08:39

このコードの場合、BITを使う意味はありません。 ループの中で毎回作り直して、毎回同じ位置にbit.addしているので、 bit.sum(1, sum+geta) は ((sum > 0) ? 1 : 0) と書いたのとまったく同じ意味となります。
actorbug

2022/11/29 13:14 編集

参考のプログラムと比較すると、内側のfor文の末尾の「bit.add(sum+geta, 1);」がコメントアウトされているため、正しい結果となりません。 あと、bitの中身を確認したいのなら、「bit.print();」と書けばよいです。
actorbug

2022/11/29 14:10

解説をまじめに読んでみましたが、BITの中身を表示しても、何をやっているか理解するのは難しそうです。 参考プログラムからリンクの貼ってある「BITで転倒数を求める」( https://qiita.com/wisteria0410ss/items/296e0daa9e967ca71ed6 )を参照するか、それでも理解できなければ、「転倒数」で検索して自分に合う解説を見つけるのがよさそうです。
SmaSTATION

2022/11/30 07:33

丁寧なご回答ありがとうございます.参照してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問