Codeforces Round #344 (Div. 2)

Posted Running_Time

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #344 (Div. 2)相关的知识,希望对你有一定的参考价值。

 

水 A - Interview

注意是或不是异或

#include <bits/stdc++.h>

int a[1005], b[1005];

int main()  {
    int n;  scanf ("%d", &n);
    for (int i=0; i<n; ++i) {
        scanf ("%d", a+i);
    }
    for (int i=0; i<n; ++i) {
        scanf ("%d", b+i);
    }
    int ans = 0;
    for (int i=0; i<n; ++i) {
        int x = 0, y = 0;
        for (int j=i; j<n; ++j) {
            x |= a[j];  y |= b[j];
            ans = std::max (ans, x + y);
        }
    }
    printf ("%d\n", ans);

    return 0;
}

B - Print Check

color[i][j] = max (timei(rowi), timej(colj)))

#include <bits/stdc++.h>

const int N = 5e3 + 5;
int a[N][N];
std::pair<int, int> row[N], col[N];

int main() {
    int n, m, k;    scanf ("%d%d%d", &n, &m, &k);
    for (int op, x, y, i=1; i<=k; ++i) {
        scanf ("%d%d%d", &op, &x, &y);
        if (op == 1) {
            row[x] = std::make_pair (y, i);
        } else {
            col[x] = std::make_pair (y, i);
        }
    }
    for (int i=1; i<=n; ++i) {
        for (int j=1; j<=m; ++j) {
            int tr = row[i].second, tc = col[j].second;
            if (tr > tc && tr > 0) {
                a[i][j] = row[i].first;
            } else if (tc > tr && tc > 0) {
                a[i][j] = col[j].first;
            }
        }
    }
    for (int i=1; i<=n; ++i) {
        for (int j=1; j<=m; ++j) {
            printf ("%d%c", a[i][j], j == m ? ‘\n‘ : ‘ ‘);
        }
    }

    return 0;
}

单调队列+排序 C - Report

题意:给m次操作,每次操作使得[1, r]范围的的a[i]升序或降序排序,问a[i]最后的结果

分析:因为左端点固定,右端点远的且操作时间靠后的可以覆盖之前右端点近的操作,所以先从右端点最远且时间靠后的时间出发,之后类似只要处理右端点降序的位置,即维护一个单调队列。队列中后一次操作长度不大于前一次长度,减少的长度k里的数字为前一次范围中前k大的数或前k小的数。

技术分享

#include <bits/stdc++.h>

const int N = 2e5 + 5;
int a[N], b[N];
int r[N], t[N];

int main() {
    int n, m; scanf ("%d%d", &n, &m);
    for (int i=1; i<=n; ++i) {
        scanf ("%d", a+i);
    }
    int s = 0;
    for (int x, y, i=1; i<=m; ++i) {
        scanf ("%d%d", &x, &y);
        while (s > 0 && y >= r[s-1])    s--;
        t[s] = x;   r[s] = y;   s++;
    }
    r[s++] = 0;

    int bl = 1, br = r[0];
    for (int i=bl; i<=br; ++i) b[i] = a[i];
    std::sort (b+1, b+1+br);

    for (int i=1; i<s; ++i) {
        for (int j=r[i-1]; j>r[i]; --j) {
            a[j] = (t[i-1] == 1) ? b[br--] : b[bl++];
        }
    }

    for (int i=1; i<=n; ++i) {
        printf ("%d ", a[i]);
    }
    puts ("");

    return 0;
}

KMP D - Messenger

题意:给两个字符串,问后者在前者里出现的次数。给出的方式:1-a 2-b 3-c 4-d(abbcccddd)

分析:其实想明白就知道这就是简单的KMP问题,文本串第一个和最后一个的个数一定要比模式串多,且里面的要完全相等。还要考虑特殊情况,压缩后m==1或2时。

#include <bits/stdc++.h>

typedef long long ll;
const int N = 2e5 + 5;
struct Part {
    ll len; char ch;
    bool operator == (const Part &rhs) const {
        return len == rhs.len && ch == rhs.ch;
    }
    bool operator >= (const Part &rhs) const {
        return len >= rhs.len && ch == rhs.ch;
    }
    bool operator != (const Part &rhs) const {
        return len != rhs.len || ch != rhs.ch;
    }
};
Part A[N], B[N];
int fail[N];

int compress(Part *C, int n) {
    int m = 0;
    for (int i=1; i<n; ++i) {
        if (C[m].ch == C[i].ch) {
            C[m].len += C[i].len;
        } else {
            C[++m] = C[i];
        }
    }
    return m + 1;
}

void get_fail(Part *P, int lenp) {
    int i = 0, j = -1;  fail[0] = -1;
    while (i < lenp) {
        if (j == -1 || P[j] == P[i]) {
            ++i; ++j;   fail[i] = j;
        } else {
            j = fail[j];
        }
    }
}

ll KMP(Part *C, int n, Part *D, int m) {
    get_fail (D, m);
    int i = 0, j = 0;
    ll ret = 0;
    while (i < n) {
        while (j != -1 && C[i] != D[j]) j = fail[j];
        i++;    j++;
        if (j == m) {
            if (C[i] >= D[m] && C[i-m-1] >= D[-1]) ret++;
            j = fail[j];
        }
    }
    return ret;
}

int main() {
    int n, m;   scanf ("%d%d", &n, &m);
    int bug = 0;
    char str[3];
    for (int i=0; i<n; ++i) {
        scanf ("%I64d-%s", &A[i].len, str);
        A[i].ch = str[0];
    }
    for (int i=0; i<m; ++i) {
        scanf ("%I64d-%s", &B[i].len, str);
        B[i].ch = str[0];
    }
    n = compress (A, n);
    m = compress (B, m);
    ll ans = 0;
    if (m == 1) {
        for (int i=0; i<n; ++i) {
            if (A[i].ch == B[0].ch) {
                ans += std::max (0ll, A[i].len - B[0].len + 1);
            }
        }
    } else if (m == 2) {
        for (int i=0; i<n-1; ++i) {
            if (A[i] >= B[0] && A[i+1] >= B[1]) ans++;
        }
    } else {
        ans = KMP (A+1, n-2, B+1, m-2);
    }
    printf ("%I64d\n", ans);

    return 0;
}

  

 

以上是关于Codeforces Round #344 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #344 (Div. 2)(按位或运算)

Codeforces Round #344 (Div. 2) C. Report 水题

Codeforces Round #344 (Div. 2) C. Report

Codeforces Round #344 (Div. 2) 631 C. Report (单调栈)

Codeforces Round #344 (Div. 2)C. Report

Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP