ACM-ICPC 2018南京赛区网络预赛 B The writing on the wall(单调栈)

解决一个有趣的问题:计算一个带有障碍物的矩形区域内的有效子矩阵数量。通过使用单调栈来高效地处理每个行元素,确保计算结果既准确又快速。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Feeling hungry, a cute hamster decides to order some take-away food (like fried chicken for only 3030 Yuan).

However, his owner CXY thinks that take-away food is unhealthy and expensive. So she demands her hamster to fulfill a mission before ordering the take-away food. Then she brings the hamster to a wall.

The wall is covered by square ceramic tiles, which can be regarded as a n * mn∗m grid. CXY wants her hamster to calculate the number of rectangles composed of these tiles.

For example, the following 3 * 33∗3 wall contains 3636 rectangles:

Such problem is quite easy for little hamster to solve, and he quickly manages to get the answer.

Seeing this, the evil girl CXY picks up a brush and paint some tiles into black, claiming that only those rectangles which don't contain any black tiles are valid and the poor hamster should only calculate the number of the valid rectangles. Now the hamster feels the problem is too difficult for him to solve, so he decides to turn to your help. Please help this little hamster solve the problem so that he can enjoy his favorite fried chicken.

Input

There are multiple test cases in the input data.

The first line contains a integer TT : number of test cases. T \le 5T≤5.

For each test case, the first line contains 33 integers n , m , kn,m,k , denoting that the wall is a n \times mn×m grid, and the number of the black tiles is kk.

For the next kk lines, each line contains 22 integers: x\ yx y ,denoting a black tile is on the xx-th row and yy-th column. It's guaranteed that all the positions of the black tiles are distinct.

For all the test cases,

1 \le n \le 10^5,1\le m \le 1001≤n≤105,1≤m≤100,

0 \le k \le 10^5 , 1 \le x \le n, 1 \le y \le m0≤k≤105,1≤x≤n,1≤y≤m.

It's guaranteed that at most 22 test cases satisfy that n \ge 20000n≥20000.

Output

For each test case, print "Case #xx: ansans" (without quotes) in a single line, where xx is the test case number and ansans is the answer for this test case.

Hint

The second test case looks as follows:

样例输入复制

2
3 3 0
3 3 1
2 2

样例输出复制

Case #1: 36
Case #2: 20

题目来源

ACM-ICPC 2018 南京赛区网络预赛

 

题意:给出一个矩形,中间有一些挖空的格子,问里面的子矩阵个数。

思路:单调栈维护,对于每一行处理的时候,每次加入一个新的列元素,单调栈里面都更新为height比它小的列,并且从前一个列的的计算结果tmp中减去除去元素的贡献,加入新列元素,再从计算结果tmp中加上他的贡献,最后加到ans中去。时间复杂度O(n*m)。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int maxm = 1e2+10;
bool box[maxn][maxm];
int up[maxm];
int ht[maxm];
int id[maxm];
int main()
{
    int t;
    int n,m,k;
    scanf("%d",&t);
    int tt = 0;
    while(t--)
    {
        memset(box,0,sizeof(box));
        memset(up,0,sizeof(up));
        scanf("%d%d%d",&n,&m,&k);
        int x,y;
        for(int i = 0;i<k;i++)
        {
            scanf("%d%d",&x,&y);
            box[x][y] = 1;
        }
        ll ans = 0;
        for(int i = 1;i<=n;i++)
        {
            ll tmp = 0;
            ll sum = 0; 
            int cnt = 0;
            for(int j = 1;j<=m;j++)
            {
                if(box[i][j])
                {
                    up[j] = i;
                    tmp = 0;
                    ht[0] = 0;
                    id[0] = j;
                    cnt = 1;
                    continue;
                }
                int h = i - up[j];
                while(cnt>0&&h<ht[cnt-1])
                {
                    if(cnt - 1>0)
                    {
                        tmp -= (id[cnt-1] - id[cnt-2])*ht[cnt-1];
                    }
                    else
                    {
                        tmp -= ht[cnt-1]*(id[cnt-1]);
                    }
                    cnt--;
                }
                if(cnt)
                {
                    tmp += (j - id[cnt-1])*h;
                }
                else
                {
                    tmp += j*h;
                }
                ht[cnt] = h;
                id[cnt++] = j;
                sum += tmp;
            }
            ans += sum;
        }
        printf("Case #%d: %lld\n",++tt,ans);
    }
}

 

 

 

### 如何为小米路由器刷入OpenWRT #### 准备工作 为了成功地将OpenWRT刷入到小米路由器中,需提前准备好必要的工具软件。这包括但不限于一台电脑用于操作、一根网线连接至路由器以及确保拥有最新的Breed固件版本支持的小米路由器型号列表[^1]。 #### 开启Telnet服务 通过特定命令或按钮激活隐藏模式下的telnet功能对于后续步骤至关重要。通常情况下,在浏览器地址栏输入`http://miwifi.com`进入管理界面后找到对应的选项来启用此特性;而对于某些特殊机型,则可能需要借助第三方应用或者按照官方文档指示完成设置过程[^2]。 #### 使用FTP上传文件 一旦开启了上述提到的服务之后就可以利用FTP客户端把breed.bin或者其他所需的镜像放置于设备内部存储空间当中去了。这里推荐使用FileZilla这类简单易用的应用程序来进行传输作业,并确认好目标路径是否正确无误[^3]。 #### 刷写Breed引导程序 当所有准备工作都已就绪之时便可以着手处理最核心的部分——即替换原有的bootloader部分为更加灵活可控的新版breed了。具体做法是在断电状态下按住reset键不放直到电源灯亮起再松手即可自动加载新安装好的环境。 #### 完成OpenWRT系统的部署 最后一步就是正式向flash芯片灌输openwrt.img映像包从而彻底改变原有操作系统架构成为基于Linux内核构建而成的强大网络平台之一。值得注意的是整个过程中要保持稳定供电以免造成不可逆损坏风险存在。 ```bash # 示例代码:通过TFTP服务器发送OpenWRT固件给路由器 tftp -l openwrt-trx-factory.bin -r /dev/mtdblock4 192.168.1.1 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值