Codeforces Round #248 (Div. 1)——Nanami's Digital Board

题目连接

  • 题意:

    给n*m的0/1矩阵,q次操作,每次有两种:1)将x,y位置值翻转 2)计算以(x,y)为边界的矩形的面积最大值

    (1?≤?n,?m,?q?≤?1000)

  • 分析:

    考虑以(x,y)为下边界的情况,h=(x,y)上边最多的连续1的个数。那么递减的枚举,对于当前hx,仅仅须要看两側能到达的最远距离,使得h(x,ty)不大于h就可以。之后的枚举得到的两側距离大于等于之前的,所以继续之前的两側距离继续枚举就可以。

const int maxn = 1100;

int n, m, q;
int ipt[maxn][maxn];
int up[maxn][maxn], dwn[maxn][maxn], lft[maxn][maxn], rht[maxn][maxn];
int len[maxn];
void updaterow(int r)
{
    FE(j, 1, m)
        lft[r][j] = (ipt[r][j] == 1 ? lft[r][j - 1] + 1 : 0);
    FED(j, m, 1)
        rht[r][j] = (ipt[r][j] == 1 ? rht[r][j + 1] + 1 : 0);
}
void updatecol(int c)
{
    FE(i, 1, n)
        up[i][c] = (ipt[i][c] == 1 ? up[i - 1][c] + 1 : 0);
    FED(i, n, 1)
        dwn[i][c] = (ipt[i][c] == 1 ? dwn[i + 1][c] + 1 : 0);
}
int maxarea(int s, int len[], int thes)
{
    int l = s, r = s, ret = 0;
    FED(i, len[s], 1)
    {
        while (l >= 1 && len[l] >= i)
            l--;
        while (r <= thes && len[r] >= i)
            r++;
        ret = max(ret, i * (r - l - 1));
    }
    return ret;
}

int main()
{
    while (~RIII(n, m, q))
    {
        FE(i, 1, n) FE(j, 1, m)
            RI(ipt[i][j]);
        FE(i, 1, n)
            updaterow(i);
        FE(j, 1, m)
            updatecol(j);
        REP(kase, q)
        {
            int op, x, y;
            RIII(op, x, y);
            if (op == 1)
            {
                ipt[x][y] ^= 1;
                updatecol(y);
                updaterow(x);
            }
            else
            {
                int ans = max(maxarea(y, up[x], m), maxarea(y, dwn[x], m));
                FE(i, 1, n)
                    len[i] = lft[i][y];
                ans = max(ans, maxarea(x, len, n));
                FE(i, 1, n)
                    len[i] = rht[i][y];
                ans = max(ans, maxarea(x, len, n));
                WI(ans);
            }
        }
    }
    return 0;
}

Codeforces Round #248 (Div. 1)——Nanami's Digital Board

时间: 2024-07-30 20:32:24

Codeforces Round #248 (Div. 1)——Nanami&#39;s Digital Board的相关文章

Codeforces Round #248 (Div. 1)——Nanami&#39;s Digital Board

题目连接 题意: 给n*m的0/1矩阵,q次操作,每次有两种:1)将x,y位置值翻转 2)计算以(x,y)为边界的矩形的面积最大值 (1?≤?n,?m,?q?≤?1000) 分析: 考虑以(x,y)为下边界的情况,h=(x,y)上边最多的连续1的个数.那么递减的枚举,对于当前hx,只需要看两侧能到达的最远距离,使得h(x,ty)不大于h即可.之后的枚举得到的两侧距离大于等于之前的,所以继续之前的两侧距离继续枚举即可. const int maxn = 1100; int n, m, q; int

Codeforces Round #248 (Div. 2) A - Kitahara Haruki&#39;s Gift

题意 给n个数,都是100或者200,问能否把这些数平均分给两个人. 思路 先算出如果平均分的话每个人要多少(sum/2),如果不能整除100那么肯定不行.如果是100的倍数,则先尽量用200的,用完200的或者已经不足200了再用100的. 代码 #include <cstdio> #include <algorithm> using namespace std; const int maxn = 110; int s[maxn]; int n; int main() { int

Codeforces Round #248 (Div. 2) B - Kuriyama Mirai&#39;s Stones

题意 给出一个n个数的序列.下面有m个指令 1指令:原序列从l到r的和 2指令:排序过的序列从l到r的和 思路 线段树可做-.直接扫一遍记录sum数组也可以 代码 #include <cstdio> #include <algorithm> #include <cstring> using namespace std; #define ll long long const int maxn = 100010; int n; int s[maxn]; int ss[max

Codeforces Round #248 (Div. 2) C - Ryouko&#39;s Memory Note

题意 一本书有n页.下面要找m个知识点,分别在s[1] s[2]-.s[m]页上. 现在有一个机会,可以把某一页的知识点全部移到另一页上.求最少的翻页次数. 如s[1] s[2] -. s[m]的翻页次数就是|s[1]-s[2]|+|s[2]-s[3]|+-+|s[m-1]-s[m]| 思路 记录每个页码在序列中前后出现的页码(如1 2 3 2 4 则2前后出现过1 3 3 4)(注意如果相邻的页码相同则不用管它) 取它们的中位数,这时一定会有移动这个页码的最优解.把所有页码遍历一遍,取整体最优

Codeforces Round #248 (Div. 1)——Ryouko&#39;s Memory Note

题目连接 题意: 给n和m,一行m个1<=x<=n的数.记c=.现在只能选择一个数x变成y,序列中所有等于x的值都变成y,求最小的c 分析: 对于一个数x,把与他相邻的所有的非x的数全部写下来.如果x增大,那么一部分值增大,一部分减小,且每个数的增大值或减小值都是x的变化值(均相等),也就是说总的结果只和比x大的数与比x小的数的数量有关,所以即中位数. const int maxn = 110000; LL ipt[maxn]; map<LL, vector<LL> >

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round 239 Div 1

都怪自己太懒了 这段时间比赛参加了大部分,但是一直都没写题解,趁这几天没事,计划把这段时间的题解都补上. 上一次比赛(248)终于升到了div1,所以从这次开始就开始写div1了. A. Triangle There is a right triangle with legs of length a and b. Your task is to determine whether it is possible to locate the triangle on the plane in such

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

DP Codeforces Round #303 (Div. 2) C. Woodcutters

题目传送门 1 /* 2 题意:每棵树给出坐标和高度,可以往左右倒,也可以不倒 3 问最多能砍到多少棵树 4 DP:dp[i][0/1/2] 表示到了第i棵树时,它倒左或右或不动能倒多少棵树 5 分情况讨论,若符合就取最大值更新,线性dp,自己做出来了:) 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 #include <cstring> 10 #include <cmath> 11 #include &