『题解』CodeForces CF548B Mike and Fun

题目传送门

题目大意

有一个 \(n \times m\)\(01\) 矩阵 \(a\)。要进行 \(q\) 次操作,每次操作将 \(a_{x,y}\) 取反,并询问连续的 \(1\) 最多的一行中连续的 \(1\) 的个数。

\(1 \le n,m \le 500,1 \le q \le 5000,1 \le x \le n,1 \le y \le m\)

思路

可以先考虑暴力。

完全按照题目中说的做,遍历每一行,在每行中找到连续的 \(1\) 最多的个数,总时间复杂度 \(\mathcal{O}(nmq)\)

然而...TLE on #15

不知道那几篇暴力题解咋过的,可能是数据又加强了吧。

然后就要考虑更快的办法了。

很容易发现,每次操作影响的只是一行,只需花 \(\mathcal{O}(m)\) 的时间将这一行重新统计一遍就行了。

可以在输入时先算出每行最多的连续个数,存入数组。在询问时 \(\mathcal{O}(n)\) 的时间遍历一遍数组求出最大值。

那么总时间复杂度就是 \(\mathcal{O}(nm+(n+m)q)\)

嘿嘿,这下你卡不到我了吧...

代码

暴力(TLE)

#include <iostream>
using namespace std;
const int N=5e2+5;
int n,m,q,x,y,sum,ans;
bool a[N][N];

int main(){
    cin >> n >> m >> q;
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            cin >> a[i][j];
        }
    }
    while(q--){
        cin >> x >> y;
        a[x][y]=!a[x][y]; // 取反
        for(int i=1; i<=n; i++,sum=0){ // 别忘了把 sum 置 0
            for(int j=1; j<=m; j++){
                if(a[i][j]) sum++; // 还是连续的,则加一
                else sum=0; // 碰到一个 0,连续就断了
                ans=max(ans,sum); // 每次都更新一下答案
            }
        }
        cout << ans << endl;
        ans=0; // 初始化
    }
    return 0;
}

预处理

#include <iostream>
using namespace std;
const int N=5e2+5;
int n,m,q,x,y,sum,ans;
bool a[N][N];
int mp[N];

int main(){
    cin >> n >> m >> q;
    for(int i=1; i<=n; i++,sum=0){ // 别忘了把 sum 置 0
        for(int j=1; j<=m; j++){
            cin >> a[i][j];
            if(a[i][j]) sum++; // 还是连续的,则加一
            else sum=0; // 碰到一个 0,连续就断了
            mp[i]=max(mp[i],sum); // 每次都更新一下答案
        }
    }
    while(q--){
        cin >> x >> y;
        a[x][y]=!a[x][y]; // 取反
        mp[x]=0; // 这句不能忘
        for(int i=1; i<=m; i++){
            if(a[x][i]) sum++;
            else sum=0;
            mp[x]=max(mp[x],sum);
        }
        for(int i=1; i<=n; i++){
            ans=max(ans,mp[i]); // 找最大值
        }
        cout << ans << endl;
        sum=0,ans=0; // 初始化
    }
    return 0;
}
posted @ 2022-02-28 22:16  仙山有茗  阅读(22)  评论(0编辑  收藏  举报