【解题报告】Codeforces Round #344 (Div. 2)

这篇博客是关于Codeforces Round #344 (Div. 2)的比赛解题报告,详细分析了每道题目A到E的思路和解决方案。其中涉及的主要技术包括兼或和性质、矩阵颜色涂色问题、单调队列优化、压缩字符串KMP匹配以及利用Convex Hull Trick求解最大ProductSum。
摘要由CSDN通过智能技术生成

$题目链接


A.Interview(Codeforces 631A)

思路

显然,根据兼或和的性质,当 l r 分别为 1 n 时最后的结果最大。

代码

#include <bits/stdc++.h>
using namespace std;

long long  n, a, b, sa, sb;

int main() {
    scanf("%d", &n);
    sa = sb = 0;
    for(int i = 0; i < n; i++) {
        scanf("%I64dd", &a);
        sa |= a;
    }
    for(int i = 0; i < n; i++) {
        scanf("%I64d", &b);
        sb |= b;
    }
    printf("%I64d\n", sa + sb);
    return 0;
}

B.Print Check(Codeforces 631B)

大意

有一个所有格子的颜色都是白色的网格。每次操作能将网格某行或某列的所有格子全部涂成某种颜色,问最后网格中每个格子的颜色是什么。

思路

显然,这题直接暴力是不行的。在不算主算法的情况下,输入的复杂度是 O(k) ,输出的复杂度是 O(nm) 。这就表示本题仅允许我们在输入的同时维护一些量,然后在输出的时候,对矩阵的每一个元素,根据这些量来决定元素的值。对于一个元素 (i,j) 而言,若要知道它最终的值是多少,仅需知道它最终被刷上什么颜色,也就是说,仅需知道它所在的行的最终颜色,它所在的列的最终颜色,以及这两个颜色出现的先后顺序。总而言之,我们需要对每一行,每一列维护最后被涂上的颜色和被涂上的时间。

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 5e3 + 5;int n, m, k, a, b, c;
int cr[maxn], cc[maxn], pr[maxn], pc[maxn];
int G[maxn][maxn];

int main() {
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= k; i++) {
        scanf("%d%d%d", &a, &b, &c);
        if(a == 1) {
            cr[b] = c;
            pr[b] = i;
        }
        else {
            cc[b] = c;
            pc[b] = i;
        }
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            G[i][j] = pr[i] > pc[j] ? cr[i] : cc[j];
        }
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            printf("%d ", G[i][j]);
        }
        puts("");
    }
    return 0;
}

C.Report(Codeforces 631C)

大意

有一个由 n 个数字组成的序列,每次可以指定序列的某个前缀,然后按照非增序或非减序为这个前缀排序。问 m 次排序之后的序列是什么。

思路

本题用暴力的方法肯定也是不行的了(复杂度为 O(mnlog(n)) )。既然题目给的每次排序的区间是前缀,那么就应该充分利用前缀的性质。不难发现,对 [0,r] 这个前缀排序以后,在这次排序之前的对长度小于 r 的前缀的排序都无效了。所以有效的前缀的长度应该是递减的。根据单调队列能够动态维护单调序列的性质,我们可以按照输入的顺序将命令序列插入单调队列,输入结束后就能得到有效的前缀序列了。接着对这些前缀依次排序就可以比暴力方法稍快地得到答案序列。不过可惜的是,这样的优化仍然不够。假设已经对长度为 ri 的前缀排序完毕。在对长度为 ri+1 的前缀排序前,我们首先可以将 [ri+1+1,r

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值