HDU 1166人の敵兵のラインナップ
トピックリンク:[vjudge] HDU 1166人の敵兵のラインナップ
アルゴリズムタグ: 树状数组
タイトル
タイトル説明
ライバル国C国の継続的な軍は、国のスパイチーフCデレクと彼の男性は忙しいTidyのアップに始めた、この時間を行使する。Nエンジニアリングキャンプのラインに沿って配置された国の海岸線は、デレクとTidyのタスクは、これらのエンジニアキャンプの活動を監視することです。高度な監視ツールのいくつかの種類の結果として、各陣営のCクリスタルクリアな把握米国でのエンジニアの数は、各陣営におけるエンジニアの数がありそうな変化を発生することがあり、増加または減少する職員の数を、彼らはCを逃れることができないことがありので、国を監視します。
「Tidyのは、すぐに10の陣営の合計の多くの人々に最初の3つのキャンプを報告:デレクTidyのは、デレクとしてどのように多くの人々 、の合計は尋ねた連続エンジニアリングキャンプの一定期間のレポートを維持するように、CIAは、行使まさに敵の戦術を研究します!「Tidyのは、すぐにこの項及び報告書の合計数を計算するために開始されます。しかし、敵のキャンプの数が多いの変化、そしてデレクは、各セグメントを尋ねたが異なっているので、Tidyのは疲れすぐに、キャンプの数に行かなければならなかったたびに、デレクはTidyの速度を計算しますますます不満:「!あなた死んで脂肪の少年は、とても遅いと考え、私はあなたを発射」Tidyのは考えた:「あなたは数学を自分で行う、本当に私はあなたがあまりにも私を解雇たい疲れる仕事であります! 「絶望では、Tidyのヘルプウインドブレーカー、ウインドブレーカーにコンピュータの専門家を呼び出すために持っていた、言った:」!死んだ脂肪少年、あなたは通常、マルチポイントACMのタイトルと呼ばないとマルチ小数点演算ブックを参照してください、今の苦い実を味わった「Tidyのは、言いました:」私は...ミスを認め「が、ウインドブレーカーは、電話を切りました。Tidyのは非常に彼は本当に、インテリジェントな読者をクラッシュをカウントしますので、あなたは彼が仕事を終える支援するプログラムを書くことができ、動揺しますか?あなたのプログラムの効率が高く十分でない場合でも、Tidyのはまだデレクさん叱られます。
入力形式
T整数最初の行は、Tは、発現データのセット。
それぞれの最初の行のデータN整数正(N <= 50000)、Nがあり、敵キャンプエンジニアを表すNとの次の正の整数、i番目のエンジニアリングキャンプを開始愛を表現するiは愛の正の整数を有します個人(1 <= <= 50愛 )。
次に、それぞれの行は、コマンドを持って、コマンドには4つの形式があります。
(1)IJを追加、i、jは正の整数であり、I番目のキャンプは、J個体(jは30を超えない)を大きく示し
、I、(2)サブIJを、jは正の整数であり、(I番目のキャンプは、J個体を低減Jを示しこれ以上30以下);
(3)クエリIJないで、i及びjは正の整数であり、iが<= J、キャンプのJ番目にクエリの総数Iを表す
。(4)の端部はそれぞれ、このコマンドデータの終了を示し最後に見られ;
40,000までの各データコマンド
出力フォーマット
「私は、ケース:」データのi番目のグループ、第一出力と、入力
INT内のこの番号のままで、各クエリのクエリのためにキャリッジリターンと出力セグメント内のクエリの総数を表す整数。
サンプル入力と出力
入力#1
1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End
出力#1
Case 1:
6
33
59
ソリューション:
フェンウィックツリー
この質問は、最初の4つの(実際には3種類)の操作のために、我々はそれがフェンウィックツリーやツリーラインで分析することができます。しかし、コードツリーラインの大量のために、そしてこの質問のために私たちは木のラインを使用する必要がありますする必要はありませんでしたということです(これはTaccaしません)、だから我々はフェンウィックツリーが解決しました。
以下のために\(追加\)と\(サブ\)コマンドには、その配列の木は明らかである一点修正。
以下のための\(クエリー\)コマンドは、それが明確なフェンウィックの木である区間の合計。
以下のために\(エンド\)コマンドで、私が言うことを知りません。
それではレビューを聞かせてどのような配列の知識の木:
\(lowbit \)
\(lowbitが\)ビット操作+ツリーによって配列を最適化するために、すべての後に、フェンウィックツリートラバーサルおよびアクセス方法であり、それはまた、フェンウィックツリーの本質である、ツリーは配列ああ\(Q_W Q \) 。
lowbit(i) = i & (-i);
修正のシングルポイント
修正の単一点もフェンウィックツリーは、プロセスの変更の単一のポイントがちょうど言うに適用される最も一般的に使用されるフェンウィックツリーいくつかの目的の一つである(\ lowbit)\、木アレイ上の次のコード\( X \)プラス\(ヴァル\) 。
void update(int x, int val) { for (int i = x; i <= n; i += i & -i) tree[i] += val; }
インターバル・お問い合わせ
あなたはそれが唯一、単一のポイントと問い合わせの単一の点を変更する必要があると言うなら、なぜフェンウィックツリーがすべき???クエリ範囲の複雑さに優れたに加えて、通常の配列に比べフェンウィックツリーも直接できるように、ここでは、クエリの範囲への道があります。
int getsum(int x) { int res = 0; for (int i = x; i; i -= i & -i) res += tree[i]; return res; }
この質問のために、私たちは与えられた指示に従って変更または照会するために段階的にしか必要です。ただし、この問題というの出力形式と複数のデータセットは、することを忘れないでください配列を空にする。
ACコード
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10;
int tree[N], num[N],T, n;
void update(int x, int val)
{
for (int i = x; i <= n; i += i & -i)
tree[i] += val;
}
int getsum(int x)
{
int res = 0;
for (int i = x; i; i -= i & -i)
res += tree[i];
return res;
}
int main()
{
scanf("%d", &T);
//cout << T << endl;
for (int tot = 1; tot <= T; tot ++ )
{
memset(tree, 0, sizeof tree);
memset(num, 0, sizeof num);
printf("Case %d:\n", tot);
scanf("%d", &n);
for (int i = 1; i <= n; i ++ )
{
scanf("%d", &num[i]);
update(i, num[i]);
}
char s[20];
while (cin >> s && s[0] != 'E')
{
int a, b;
scanf("%d%d", &a, &b);
if (s[0] == 'Q')
{
//cout << 1 << endl;
int ans = getsum(b) - getsum(a - 1);
printf("%d\n", ans);
continue ;
}
if (s[0] == 'A')
{
//cout << 2 << endl;
update(a, b);
continue ;
}
if (s[0] == 'S')
{
//cout << 3 << endl;
update(a, -b);
continue ;
}
}
}
return 0;
}