zoukankan      html  css  js  c++  java
  • 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
    ", 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 ? '
    ' : ' ');
            }
        }
    
        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
    ", ans);
    
        return 0;
    }
    

    凸包 E - Product Sum

    题意:将一个点移动到另一个点(可相同),求

    分析:推算化简的得到: 

            或者 

    先考虑后者,再次化简得到:,可以抽象成ax+b, (x = ar),所以我们枚举ar,得到最大的,用到了凸包,把直线加入凸包,得到单调上升的类似于这样的,然后二分找最大值。前者类似。

    第一次碰到这种题,写详细点:)

    #include <bits/stdc++.h>
    
    typedef long long ll;
    const int N = 2e5 + 5;
    int a[N];
    ll sum[N];
    
    struct Line {
        int a; ll b;
        ll get(int x) {
            return 1ll * a * x + b;
        }
    };
    struct Convex_hull {
        int sz;
        Line *hull;
        Convex_hull(int maxn) {
            hull = new Line[++maxn]; sz = 0;
        }
        void clear() {
            sz = 0;
        }
        bool is_bad(int cur, int pre, int nex) {
            Line c = hull[cur], p = hull[pre], n = hull[nex];
            return (c.b - n.b) * (c.a - p.a) <= (p.b - c.b) * (n.a - c.a);
        }
        void add_line(int a, ll b) {
            hull[sz++] = (Line) {a, b};
            while (sz > 2 && is_bad (sz-2, sz-3, sz-1)) {
                hull[sz-2] = hull[sz-1]; sz--;
            }
        }
        ll query(int x) {
            int low = -1, high = sz - 1;
            while (low + 1 < high) {
                int mid = low + high >> 1;
                if (hull[mid].get (x) <= hull[mid+1].get (x)) {
                    low = mid;
                } else {
                    high = mid;
                }
            }
            return hull[high].get (x);
        }
    };
    
    int main() {
        int n; scanf ("%d", &n);
        ll ans = 0; sum[0] = 0;
        for (int i=1; i<=n; ++i) {
            scanf ("%d", a+i);
            sum[i] = sum[i-1] + a[i];
            ans += 1ll * a[i] * i;
        }
        Convex_hull *hull = new Convex_hull (n);
        ll add = 0;
        for (int r=2; r<=n; ++r) {
            hull->add_line (r-1, -sum[r-2]);
            add = std::max (add, hull->query (a[r]) + sum[r-1] - 1ll * a[r] * r);
        }
        hull->clear ();
        for (int l=n-1; l>=1; --l) {
            hull->add_line (-(l+1), -sum[l+1]);
            add = std::max (add, hull->query (-a[l]) + sum[l] - 1ll * a[l] * l);
        }
        printf ("%I64d
    ", ans + add);
    
        return 0;
    }
    

      

    编译人生,运行世界!
  • 相关阅读:
    Vim+Vundle+YouCompleteMe 安装
    TortoiseSVN 的分支合并操作
    JSP数据交互一
    Jquery操作DOM
    Jquery
    JQuery选择器
    第五章初始JQuery
    JavaScript对象及初识面向对象
    JavaScript第三章操作DOM
    JavaScript第二章操作BOM
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5246528.html
Copyright © 2011-2022 走看看