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

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

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

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

Q&A

解決済

2回答

907閲覧

i += i & -i; この動作がわからないです。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

0グッド

1クリップ

投稿2021/06/05 05:17

教えていただきたいこと

以下のソースのadd関数とgetSum関数にある**i += i & -i;この1文のi**の動きがわからないです。

該当のソースコード

c++

1#include <bits/stdc++.h> 2 3using namespace std; 4 5const int N = 100000 ; 6int size, c, L[N], R[N], tree[2*N+1]; 7vector<int> vec[N]; 8 9void init(int v) { 10 L[v] = ++c; 11 for (int i = 0; i < vec[v].size(); i++) { 12 init(vec[v][i]); 13 } 14 R[v] = ++c; 15} 16 17void add(int i,int x) { 18 while (i <= size) { 19 tree[i] += x; 20 i += i & -i; 21 } 22} 23 24int getSum(int i) { 25 int ans = 0; 26 while (i > 0) { 27 ans += tree[i]; 28 i -= i & -i; 29 } 30 return ans; 31} 32 33void query(int i) { 34 if (i == 0) { 35 int v, w; 36 cin >> v >> w; 37 add(L[v], w); 38 add(R[v], -w); 39 } else { 40 int v; 41 cin >> v; 42 cout << getSum(R[v] - 1) << endl; 43 } 44} 45 46int main() { 47 int n; 48 cin >> n; 49 c = 0; 50 size = 2 * n + 1; 51 52 for (int i = 0; i < n; i++) { // input node // 53 int k; 54 cin >> k; 55 for (int j = 0; j < k; j++) { 56 int child; 57 cin >> child; 58 vec[i].push_back(child); 59 } 60 } 61 62 init(0); 63 64 int q; 65 cin >> q; 66 for (int i = 0; i < q; i++) { // input query // 67 int op; 68 cin >> op; 69 query(op); 70 } 71 72 return 0; 73}

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/06/05 08:17

申し訳ありませんがそちらではございません。 よろしければリンクする必要性をお教えください。
Zuishin

2021/06/05 08:22

義務です。著作権について調べてください。
BeatStar

2021/06/05 08:33

リンクする必要ですか? それは、『問題文を出さずに答えだけ出されても意味不明である』です。 たとえば、仕様的に間違っていることもあります。 プログラムは書かれた通りにしか動きません。 そもそも、プログラムは『こう書けばいい』っていうものじゃないのです。 なので、『ソースを提示しろ』と言われているのでは?
退会済みユーザー

退会済みユーザー

2021/06/05 10:12

今回載せているソースコードは部分的に参考にしていますが、おおよそ自分で書いたものになります。質問している2つの関数について著作権が発生するのであればそれに準じた行いをすべきだと思いますが今回は必要がないと判断させていただきました。 リンクを貼れとのことでしたが、貼ったらいい、貼ることが義務といったものは見受けられませんでした。 また、beatstarさんの仰っている問題を載せろとのことですが、上記の部分の動きのみを知りたかったのでかえって知りたいことの阻害になると思い載せませんでした。
Zuishin

2021/06/05 10:13

著作権を調べたら「引用」の定義もすぐ見つかるはずなので。
BeatStar

2021/06/05 10:21

あー、別に『必ず載せろ』という意味で書いたのではなく、『他の方の仰っている意味』を書いただけです。 >> また、beatstarさんの仰っている問題を載せろとのことですが 必ず載せるべきと言うわけではなく、『ソースコードだけでは何がしたいのかが不明瞭な場合がある』ため、上記でそう書いたんです。 回答者からすると、場合によっては『情報の後出し』感が半端ないこともあります。 なので上記のような書き方になりました。
退会済みユーザー

退会済みユーザー

2021/06/05 10:24

参考のため伺いたいのですが、今回のケースは問題がわからないと回答は困難、難解になると思いますか?
BeatStar

2021/06/05 10:30 編集

今回の場合はそこまで重要というほどでないですが、時折、仕様によることもあるので。 たとえば、他の質問者さんのものであったのですが、『わかっていない部分と質問文がかい離している』のがありました。 (トラブルのもとになりそうなので伏せますが) そういう風に、『場合による』こともあるので、今回、私は彼/彼女の仰っていることをもうちょっと踏み込んで書いただけです。
退会済みユーザー

退会済みユーザー

2021/06/05 10:28

ありがとうございます。
Zuishin

2021/06/05 10:44

自分で書いたものの意味を尋ねる質問をする人はいないでしょう。 他人の書いたものは他人の著作物で、それを複製することは他人の権利を侵害する不法行為であり、犯罪です。 引用の場合はそれにあたりませんが、厳格なルールがあり、出典を示すというのは引用の要件を満たすために必要な要素の一つです。 出典を示さずソースコードを複製することは犯罪です。 回答者のためではなく、著作権者と自分のために必ず載せなければいけません。
退会済みユーザー

退会済みユーザー

2021/06/05 11:06

例えばですがある1文をコピーした際、著作権侵害を問われることはないと考えます。今回の件、1部を参考にさせていただきましたがその部分に関しては汎用性の高さから重要度が低いと考えられます。 今回の質問は当人からの削除依頼を受け取り次第、削除させていただきます。
Zuishin

2021/06/05 12:04

問われることがあるかないか調べたらすぐわかることなので調べたらいいでしょう。 文には著作権があります。
Zuishin

2021/06/05 12:06 編集

他人の作ったものを引用する時に出典を書くのは **常識**なので、グダグダ言うことではありません。 大学に行ったことのある人であれば普通に知っています。 書かない場合、書けない理由があるようにしか見えませんね。
退会済みユーザー

退会済みユーザー

2021/06/05 12:14

貴方様は当ソースコードの著作権の所有者様なのでしょうか? その場合はそれがわかるように証明していただければ削除させていただきます。 また、気に入らないようでしたら運営様に問い合わせして削除依頼などをしてはいかがでしょうか。 そうなった場合は適当な処罰も受け入れます。 ご苦労様でした。貴重なご意見ありがとうございます。
Zuishin

2021/06/05 13:05

私が所有者なら削除依頼しろ? 私が所有者じゃなければ見つかってないので何もしない? やっぱり自分で書いたんじゃなく人のものを盗んできたんじゃないか。犯罪者。
退会済みユーザー

退会済みユーザー

2021/06/05 13:17

犯罪者という認識で大丈夫です。望むなら通報でもしていたいて結構です。
Zuishin

2021/06/05 13:52

通報するしない、捕まる捕まらないの問題じゃない。
Zuishin

2021/06/05 13:53

他人の著作物に敬意を払えないようなやつにプログラミングする資格はない。
guest

回答2

0

ベストアンサー

i += i & -i

i & -iについては、iの最下位の立っているビットのみが1でそれ以外が0になります。
iと加算する事で最下位の立っているビットを0にし、その直上のビットに1を繰り上げます。

投稿2021/06/05 06:02

asm

総合スコア15149

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

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

0

i & -i;

i が0の場合は0、それ以外は1ってことなんでしょうね

投稿2021/06/05 06:47

y_waiwai

総合スコア88042

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

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

退会済みユーザー

退会済みユーザー

2021/06/05 06:56

addやgetSum関数の具体的な動きをお教えいただけないでしょうか
BeatStar

2021/06/05 08:25

私もはっきりとわかっていませんが、それって、 &&の方では?
episteme

2021/06/05 08:59

i = 0, 1, 2, 3... で i & -i の値は 0, 1, 2, 1, 4, 1, 2, 1, 8 ... ですけど。
can110

2021/06/05 10:12

回答する前に、デバッグ環境を整えて、実際に動きを確かめてみましょう。 デバッグ環境を使うと、ソースコードの任意の場所で実行を止め、変数のナカミを確認できます。 また、ワンステップづつ実行させてコードの動きを確認できます そうすれば、間違った回答をせずに済むようになります
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問