プログラミング思考第5週の割り当てB-TTのMagic Cat

タイトル

ある日、魔法の猫はTTに問題を与えることによってTTの能力を調査することを決定しました。つまり、世界地図からn個の都市を選択し、a [i]はi番目の都市が所有する資産価値を表します。
その後、魔法の猫はいくつかの操作を実行します。各ターンでは、間隔[l、r]で都市を選択し、資産価値をcずつ増やします。そして最後に、q回の運用後に各都市の資産価値を与える必要があります。

入力

最初の行は二つの整数N、Q(1≤n、q≤2⋅10含ま5都市や操作の数を- )。
整数のA1、A2、...、(-10:2行目は、配列Aの要素を含んでいる6 ≤ai≤10 6)。
次にq行が続き、各行は操作を表します。i番目の行は三つの整数L、R及びC(1≤l≤r≤n、-10含ま5 ≤c≤10 5、i番目の操作のために)。

出力

1行に1つのn個の整数a1、a2、…、1つを出力します。aiは、i番目の都市の最終的な資産値と等しくなければなりません。

入力例

4 2
-3 6 8 4
4 4 -2
3 3 1

出力例

-3 6 9 2

アイデア

質問の意味は単純に思われますが、間隔内のポイントを1つずつ直接変更すると、複雑さはO(qn)となり、タイムアウトになります。
範囲内のすべての点が操作されるため、プレフィックスの和と差を使用して、元の配列を差の配列に変換し、間隔の変更を点の変更に変更できます。
新しい配列b [i] = a [i] -a [i-1](i> = 1)の場合、b []は2つの隣接するアイテム間の差異をa []に記録します。また、[1]も変更される可能性があるため、a [0]は0として割り当てられますb []をa []に復元するための基礎として、変更されません。
次に、間隔[l、r]の間のポイントの値を変更するときは、b [l]b [r + 1]、それは[l]と[l-1]の違いそして[r + 1]と[r]の違い
b[]转为a[]时,a[i]=a[i-1]+b[i]。

コード

#include <cstdio>
#include <algorithm>
using namespace std;
long long a[200005],b[200005];//范围q*n最大为2*10^10

int main() {
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)//从1开始,留出a[0]=0,a[1]要与a[0]查分,要有一个固定的开始值
        scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
        b[i]=a[i]-a[i-1];
    for(int i=0;i<q;i++){
        int l,r,c;
        scanf("%d%d%d",&l,&r,&c);
        b[l]+=c;
        b[r+1]-=c;
    }
    for(int i=1;i<=n;i++)
        a[i]=a[i-1]+b[i];
    for(int i=1;i<=n;i++)
        printf("%lld ",a[i]);
}

まとめ

データ範囲に注意してくださいlong longを使用する必要があります将来的には、取得したデータ範囲を大まかに計算して適切なタイプを使用する必要があります。
タイトルリンク

元の記事を24件公開 賞賛2件 訪問数435件

おすすめ

転載: blog.csdn.net/weixin_43805228/article/details/105170027