P7410 题解

看不懂大佬思路的看过来,本文将详细地带你讲解(图文结合)。本题解思路来自12345678hzx,为了方便理解,变量名大部分和 hzx 相同。

思路

前置知识:ST 表。运用 $n$ 维的 $minn$ 数组求最小值。$minn_{i,j,k}$ 表示第 $i$ 行第 $j$ 个数及后面共 $2^k$  个数的最小值,这里不重点展开来讲。

部分代码


    scanf("%lld",&n);
    for(int i = 1;i <= n;i++) for(int j = 1;j <= n;j++) scanf("%lld",&mmin[i][j][0]);
    for(int k = 1;k <= n;k++) {
        for(int j = 1;(1 << j)  <= n;j++) {
            for(int i = 1;i + (1 << (j - 1)) <= n;i++) {
                mmin[k][i][j] = min(mmin[k][i][j - 1],mmin[k][i + (1 << (j - 1))][j - 1]);
            }
        }
    }

接着,我们枚举长方形的左边,右边和底边,计算一共可以取几个。左边,右边我用 $i,j(i \le j)$ 表示,底边用 $k$ 表示。$x,y$ 分别表示上一个最小值小于 $100$ 的行和上一个最小值等于 $100$ 的行。下面的图片是初始情况。

如图所示,第一行 $i$ 列到 $j$ 列的最小值小于 $100$,我们更新 $y \gets 1$。因为以 $k$ 为底的不可能有,所以 $ans$ 不变。

如图所示,当 $k = 2$ 时最小值等于 $100$。我们更新 $x \gets 2$。因为以 $x$ 为底的共可以有 $x - y$ 个,所以 $ans \gets ans + x - y$

如图所示,当 $k = 3$ 时最小值大于 $100$。这时需要分类讨论:当 $x > y$$ans \gets ans + x - y$(与 $k = 2$ 时同理)。否则 $ans$ 不变(因为在取到最小值等于$100$ 的同时也会取到最小值小于 $100$ 的)。

所以,经过每次操作后,我们只需要将 $ans \gets ans + \max(x - y,0)$


部分代码


for(int i = 1;i <= n;i++) llog[i] = log(i) / log(2);//表示 i 在二进制下的位数,需要预先储存避免重复运算。
    for(int i = 1;i <= n;i++) {
        for(int j = i;j <= n;j++) {
            int x = 0,y = 0;
            for(int k = 1;k <= n;k++) {
                int v = llog[j - i + 1];
                int s = min(mmin[k][i][v],mmin[k][j-(1<<v)+1][v]);//取出最小值
                if(s < 100) y = k;
                if(s == 100) x = k;
                ans += max((long long)0,x - y);
            }
        }
    }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值