ブラシタイトルノート - とプレフィックス

接頭語と衝突する迅速で静的配列を特定の範囲内の方法およびすべての数。変化は、配列を確認する過程で発生した場合、フェンウィック木、木ライン及び他の方法を用いることができます。

例1と一次元の接頭辞

長さのシーケンスを入力nは整数です。
次に、その後、m個の入力クエリ、入力クエリL、Rの各対。
クエリごとに、LとRの数に元のシーケンス番号から出力。
入力フォーマットは、
最初の行は二つの整数nとmを含有します。
2行目は、整数列の数を表す整数N含有します。
その後各行は、クエリの間隔範囲を表す2つの整数LとRを含む、行をMです。
出力フォーマット
コm行、各行は、問い合わせの結果を出力します。

データ範囲

\(\1≤l≤r≤n)
\(1≦nは、m≤100000\)
\( - 1000≤≤1000\の要素数の値)

#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n,m;
int s[N];
int a[N];
int main(void)
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d",&a[i]);
        s[i] = s[i-1] + a[i];
    } 
    while(m--)
    {
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d\n",s[r] - s[l-1]);
    }
    return 0;
    
}

例2次元の接頭辞と

n行m列の整数行列を入力し、クエリqを入力し、4つの整数のX1、Y1、X2、Y2、左上座標を含む各チャレンジと右座標を低くする部分行列を表します。
各サブクエリ出力行列とすべての数字のために。
入力フォーマットは、
最初の行は三つの整数N、M、Qを含有します。
次のnラインは、各ラインは、整数mは整数行列を表す含ま。
次Qの行は、4つの整数X1、Y1、X2、Y2を構成する各列は、クエリの基を表します。
出力フォーマット
コq行、各行は、問い合わせの結果を出力します。
データ範囲
\(1≦nは、m≤1000\)
\(1≤q≤200000\)
(\1≤x1≤x2≤n)\
\( - 1000≤行列要素値≤1000\以内)

#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1010;
int a[N][N];
int s[N][N];
int n,m,q;
int main(void)
{
    scanf("%d%d%d",&n,&m,&q);
    for(int i = 1; i <= n;i++)
        for(int j = 1; j <= m;j++)
        {
            scanf("%d",&a[i][j]);
            s[i][j] = s[i -1][j] + s[i][j-1] - s[i-1][j-1] + a[i][j];
        }
    while(q--)
    {
        int x1,x2,y1,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%d\n",s[x2][y2] - s[x2][y1-1] - s[x1-1][y2] + s[x1-1][y1-1]);
    }
    return 0;
    
            

}

演習1 K間隔回

連続したサブシーケンスは、Kの合計の倍数である場合、我々はこの間隔を呼び出す、請求列数Nの長さを与えられた[私は、j]をK倍間隔です。
あなたはK倍それ区間の合計数の列数を見つけることができますか?

データ範囲

\(1≤N、K≤100000\)
\(1≤Ai≤100000\)

アイデア:

  1. 制御配列の二重ループの開始位置と終了位置によって、それぞれ各サブシーケンスのトラバーサル要求及びS [R] - S [L -1]%kが0に等しい、時間複雑性はある(O(N ^ \ 2)\)\ 10 ^ 9(\)ための、時間の複雑さを下げることを検討する必要があります。
    2.一般的な方法は、時間の複雑さ軽減することである時間のためのスペースを
  2. S [R] - S [L -1]%K == 0は、 S [R]と等価である%K == S [L-1]%K、Sの残りの部分を格納するために使用される配列を宣言することが可能である[I]数の%kは、これだけは、循環していること
    4.なお、データのオーバーフロー

コード:

#include <cstring>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n,k;
LL s[N],cnt[N];
int main(void)
{
    scanf("%d %d",&n,&k);
    //计算前缀和
    for(int i = 1; i <= n;i++){
        scanf("%lld",&s[i]);     //注意LL的读取
        s[i] += s[i-1];
    }
    LL ans = 0;                 //注意答案可能溢出
    for(int i = 0;i <= n;i++)   //考虑和为0也也是k倍区间,所以从0开始遍历
    {
        //假设已经有两个S[i]的余数为x,则又有一个S[i]%k == x时,会产生两个新的答案,所以有下面两句
        ans += cnt[s[i] % k];
        cnt[s[i] % k]++;
    }
    printf("%lld",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/zy200128/p/12616856.html