zoukankan      html  css  js  c++  java
  • Codeforces 548B Mike and Fun

    B. Mike and Fun
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Mike and some bears are playing a game just for fun. Mike is the judge. All bears except Mike are standing in an n × m grid, there's exactly one bear in each cell. We denote the bear standing in column number j of row number i by (i, j). Mike's hands are on his ears (since he's the judge) and each bear standing in the grid has hands either on his mouth or his eyes.

    They play for q rounds. In each round, Mike chooses a bear (i, j) and tells him to change his state i. e. if his hands are on his mouth, then he'll put his hands on his eyes or he'll put his hands on his mouth otherwise. After that, Mike wants to know the score of the bears.

    Score of the bears is the maximum over all rows of number of consecutive bears with hands on their eyes in that row.

    Since bears are lazy, Mike asked you for help. For each round, tell him the score of these bears after changing the state of a bear selected in that round.

    Input

    The first line of input contains three integers nm and q (1 ≤ n, m ≤ 500 and 1 ≤ q ≤ 5000).

    The next n lines contain the grid description. There are m integers separated by spaces in each line. Each of these numbers is either 0 (for mouth) or 1 (for eyes).

    The next q lines contain the information about the rounds. Each of them contains two integers i and j(1 ≤ i ≤ n and 1 ≤ j ≤ m), the row number and the column number of the bear changing his state.

    Output

    After each round, print the current score of the bears.

    Sample test(s)
    input
    5 4 5
    0 1 1 0
    1 0 0 1
    0 1 1 0
    1 0 0 1
    0 0 0 0
    1 1
    1 4
    1 1
    4 2
    4 3
    output
    3
    4
    3
    3
    4

     ——————————————————————————————————————————————————————————————

    本来挺简单的一道题,我却写得很复杂。不善于分析复杂度是硬伤啊!

    ———————————————————————————————————————————————————————————————

    1. 读入复杂度N×M,这说明若果算法在与N×M相当的复杂度内是可以AC的

    2. 对于一个长为L的01序列,可在O(L)时间内得到连续1的最大数目 (the maximum number of consecutive "1" s in it)。

    int a[MAX_N];
    int ans=0, cur=0;
    for(int i=1; i<=n; i++){
        if(a[i]==1){
            cur++;
            ans=max(ans, cur);
        }
        else cur=0;
    }

    这个基本方法我却没想到,把简单问题搞得过于复杂,没怎么仔细考虑就决定用线段树维护,而且这线段树写得还很“丑陋”。

    #include<bits/stdc++.h>
    using namespace std;
    const int MAX_N=505;
    //SegT_1
    struct node{
        int lb, rb;
        int ma;
    }T[MAX_N][MAX_N<<2];
    void renew(int i, int id){
        node &now=T[i][id];
        if(now.ma){
            now.lb=now.rb=now.ma=0;
        }
        else{
            now.ma=now.lb=now.rb=1;
        }
    }
    void _renew(int i, int id, int L, int R){
        node &fa=T[i][id], &ls=T[i][id<<1], &rs=T[i][id<<1|1]; 
        fa.lb=ls.lb==(R-L+2)>>1?ls.lb+rs.lb:ls.lb;
        fa.rb=rs.rb==(R-L+1)>>1?rs.rb+ls.rb:rs.rb;
        fa.ma=max(max(ls.ma, rs.ma), ls.rb+rs.lb);
    }
    void insert(int i, int id, int L, int R, int pos){
        if(L==R){renew(i, id);return;}
        int mid=(L+R)>>1;
        if(pos<=mid) insert(i, id<<1, L, mid, pos);
        else insert(i, id<<1|1, mid+1, R, pos);
        _renew(i, id, L, R);
    }
    //SegT_2
    int mx[MAX_N<<2];
    void _insert(int id, int L, int R, int pos, int val){
        if(L==R){mx[id]=val; return;}
        int mid=(L+R)>>1;
        if(pos<=mid) _insert(id<<1, L, mid, pos, val);
        else _insert(id<<1|1, mid+1, R, pos, val);
        mx[id]=max(mx[id<<1], mx[id<<1|1]);
    }
    //
    int main(){
        freopen("in", "r", stdin);
        int N, M, Q;
        cin>>N>>M>>Q;
        int a;
        for(int i=1; i<=N; i++){
            for(int j=1; j<=M; j++)
                if(cin>>a, a) insert(i, 1, 1, M, j);
            _insert(1, 1, N, i, T[i][1].ma);
        }
        int i, j;
        while(Q--){
            cin>>i>>j;
            insert(i, 1, 1, M, j);
            _insert(1, 1, N, i, T[i][1].ma);
            cout<<mx[1]<<endl;
        }
        return 0;
    }

    甚至于我还在想能不能在不牺牲时间复杂度的情况下将树状数组改造成支持单点改的RMQ(不想写两个线段树~<^>~),但我真是SB了。这题暴力的复杂度O(q(n+m)) (读入复杂度O(nm)相比之下可忽略了), 1e6的量级,1s完全可过了(况且都说Codeforces的机器快~)。

    -----------------------------------------------------------------------------------------------------------------------

    写复杂的原因呢,就是我不熟悉求一个01串内最长连续“1”的长度朴素的解法应该怎么写(怎么可以连这都不知道呢~),最终踏上了线段树的歧途。

    (×&^伤#¥%), 最要紧的还是要把一些基础姿势get到。

  • 相关阅读:
    详细讲解Linux下安装python3(Python3.5.4)
    JavaScript抽象语法树英文对照
    关于MacBook Pro外接4K/60HZ显示器的问题
    Vue组件v-if新渲染的组件不更新
    Vue 子组件与子组件之间传值
    Spring整合CXF步骤,Spring实现webService,spring整合WebService
    CXF错误:Unsupported major.minor version 51.0,java.lang.UnsupportedClassVersionErro
    springMvc中406错误解决,springMvc使用json出现406 (Not Acceptable)
    jquery.validate中使用remote,remote相同值不校验问题解决
    MyBatis返回主键,MyBatis Insert操作返回主键
  • 原文地址:https://www.cnblogs.com/Patt/p/4712398.html
Copyright © 2011-2022 走看看