Codeforces 548B Mike and Fun
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.
InputThe first line of input contains three integers n, m 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.
OutputAfter each round, print the current score of the bears.
Sample test(s) input5 4 5output
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
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到。
- 系统节拍的使用
- iPhone开发入门系列2(iOS8+Swift版)备忘录APP学习01
- 犀牛——第7章 7.3稀疏数组
- python的win32操作
- python的一些图像操作
- hdu 3874 Necklace (树状数组+离线操作)
- HDOJ 2317 Nasty Hacks
- Android入门——Handler机制
- hdu 3333 Turing Tree (树状数组+离线处理+离散化)
- post 提交数据
- 黑马程序员——数组转换(二进制-八进制-十六进制)-第6天
- OC_NSUseDefault
- 黑马程序员_java_面向对象总结
- 黑马程序员_java_集合总结(下)
- 黑马程序员_java_集合总结(上)
- 黑马程序员_java_反射总结
- 程序员该有的艺术气质—SOLID原则
- 黑马程序员_java_多线程总结(下)
- MySQL调优 ---- IN
- 黑马程序员_java_IO流总结(下)