Codeforcesエドゥラウンド48 AD

A.デスノート

シンプルなシミュレーション、利用可能\(\%の\)\(/ \)コードの量を減らすために

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 200010;
int n, m, a[N], cnt = 0, tot = 0;
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++){
        scanf("%d", a + i);
        cnt = (tot + a[i]) / m;
        tot = (tot + a[i]) % m;
        printf("%d ", cnt);
    } 
}

B - セグメントオカレンス

前処理\(A、B \)\(ハッシュ\)テーブルは、時間計算をするために低減することができる\(O(QN)\)

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef unsigned long long ULL;
const int N = 1010, B = 221;
int n, m, q, len;
char s[N], t[N]; 
ULL P[N], S[2][N];
ULL inline get(int l, int r, int c){
    return S[c][r] - S[c][l - 1] * P[r - l + 1];
}
int main(){
    scanf("%d%d%d%s%s", &n, &m, &q, s + 1, t + 1);
    P[0] = 1;
    for(int i = 1; i <= n; i++){
        P[i] = P[i - 1] * B;
        S[0][i] = S[0][i - 1] * B + s[i];
        S[1][i] = S[1][i - 1] * B + t[i];
    }
    while(q--){
        int l, r, res = 0; scanf("%d%d", &l, &r);
        for(int i = l; i <= r - m + 1; i++)
            if(get(i, i + m - 1, 0) == get(1, m, 1))res++;
        printf("%d\n", res);
    }
    return 0;
}

C - Vasyaやキノコ

+プレフィックスとハードコアシミュレーションプロセス。そうでなければエンド周り繰り返し\(2 * N \)左上、またはから出発して、格子\(S \)の周りに、円の周りに数回形状、又は全体ラップの周り。

約列挙でき\(S \)格子の数を、\(S \)接頭部が算出してもよいし、係数が同じである、計算の後部は、より複雑です。

例1

最初の場合、いくつかの完全な周りの前部\(U- \) トップからスタート。

(検索になりました\)(\代わって(U \)\ A列の数の単語端(含みます)):

上部半分:$ \ sum_ {I =今+ 1} ^ NA [0] [i]は*(iは2 *)$

私たちは、列の数と接尾辞と接尾辞であることがわかりました。

\(sufx [J] = \ sum_ {iがjは=} ^ NA [I] *(I - J + 1)[J] * 1 + [J + 1] * 2 + ... + [N] = *(n - でJ + 1)\)

したがって、\(sufx [今+ 1] \) プラス\(\ sum_ {J} ^ = IのNa [I] *(I※2 - 。1)\) その答え、利用可能な後部延長のこの部分はそして、\(O(1)\)計算されます。

下部半分:$ \ sum_ {I =今+ 1} ^ NA [1]〜[I] *(N +(N - I + 1))$

我々のような何かをしたいです:

\([I] * 3 + [I + 1] * 2 + [I + 2] * 1 \)

これがどのように見える\(ハッシュ\)テーブルの原則が、\(B = 1 \) あなたのアイデアのハッシュテーブルを使用することができます\(O(1)\)これを取得するために、次にサフィックスを追加します要因のいずれか。

ケース2

第二のケースではなく、上下逆さまにされ、我々はアプローチを交換することができます。

前処理接頭辞と接尾辞、および列挙と\(S \)時間である\(O(N)\) それぞれが解決単に\(O(1)\)、$の複雑さの合計はOであるように( N)の$

#include <cstdio>
#include <iostream>
#include <cmath>
 
using namespace std;
typedef long long LL;
const int N = 300010;
//s形的预处理
int n, a[2][N];
LL pre[2][N], s[2][N], suf[2][N], sum[N], prex[2][N], sufx[2][N], ans = -1;
 
 
int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &a[0][i]);
    for(int i = 1; i <= n; i++) scanf("%d", &a[1][i]);
    int S = n >> 1, tot = 0;
    for(int i = 1; i <= S * 2; i+=2){
        s[0][i] = (LL)a[0][i] * (tot++); s[1][i] = (LL)a[1][i] * (tot++);
        s[1][i + 1] = (LL)a[1][i + 1] * (tot++); s[0][i + 1] = (LL)a[0][i + 1] * (tot++); 
    }

   
    for(int i = 0; i < 2; i++)
        for(int j = 1; j <= n; j++){
            pre[i][j] = pre[i][j - 1] + a[i][j];
            prex[i][j] = prex[i][j - 1] + pre[i][j];     
        }
    
    for(int j = 0; j < 2; j++)
        for(int i = n; i >= 1; i--){
            suf[j][i] = suf[j][i + 1] + a[j][i]; 
            sufx[j][i] = sufx[j][i + 1] + suf[j][i]; 
        }
 
    for(int i = 0; i <= n; i++){
        LL tot = sum[i] = sum[i - 1] + s[0][i] + s[1][i];
        //如果是奇数,则在下面出发
        if(i % 2){
            tot += (n + i - 1) * suf[0][i + 1] + (prex[0][n] - prex[0][i] - (n - i) * pre[0][i]);
            tot += (i * 2 - 1) * suf[1][i + 1]  + (sufx[1][i + 1]);
        }else{
            //从上面出发
            tot += (i * 2 - 1) * suf[0][i + 1] + (sufx[0][i + 1]);
            tot += (n + i - 1) * suf[1][i + 1] + (prex[1][n] - prex[1][i] - (n - i) * pre[1][i]);
        }
        ans = max(ans, tot);
    }

    printf("%lld", ans);
    return 0;
}

D - Vasyaとマトリックス

リファレンス問題解決。XOR参照の性質の有無、\(X \) \(XOR \) $ $ X = 0。

ちょうど最後の行、追加のすべての番号の最後の1に加えて、合理的な配列を構築考えてみましょう\(0 \)

他のデータの右下隅に加えて異なると数、右下隅をコピーしたりしようとすることができます。

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 110;
int n, m, a[N], b[N], ans = 0;
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", a + i), ans ^= a[i];
    for(int i = 1; i <= m; i++) scanf("%d", b + i), ans ^= b[i];

    if(ans != 0)puts("NO");
    else{
        puts("YES");
        ans = b[m];
        for(int i = 1; i < n; i++){
            for(int j = 1; j < m; j++)
                printf("0 ");
            printf("%d\n", a[i]);
            ans ^= a[i];
        }
        b[m] = ans;
        for(int i = 1; i <= m; i++) printf("%d ", b[i]);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/dmoransky/p/11247607.html
おすすめ