题解:「NOIP2022 提高组」种花

题目大意:给定一个 \(n \times m\) 的01矩阵,0表示可以种花,1表示土坑(无法种花),现在要在图上种出一个C型或F型(C,F横着的两条线的长度都可以不同,但一定是面向右边的),现在问你种C和F分别有多少种方案(除了这个形状外不能在任何地方种花),多组数据,\(T \leq 5\)。 答案对998244353取模 。

原题面中对形状的定义是这样的:

一种种花方案被称为 \(\texttt{C-}\) 的,如果存在 \(x_1, x_2 \in [1, n]\),以及 \(y_0, y_1, y_2 \in [1, m]\),满足 \(x_1 + 1 < x_2\),并且 \(y_0 < y_1, y_2 \leq m\),使得第 \(x_1\) 的第 \(y_0\) 到第 \(y_1\) 、第 \(x_2\) 的第 \(y_0\) 到第 \(y_2\) 以及第 \(y_0\) 的第 \(x_1\) 到第 \(x_2\) 不为土坑,且只在上述这些位置上种花。

一种种花方案被称为 \(\texttt{F-}\) 的,如果存在 \(x_1, x_2, x_3 \in [1, n]\),以及 \(y_0, y_1, y_2 \in [1, m]\),满足 \(x_1 + 1 < x_2 < x_3\),并且 \(y_0 < y_1, y_2 \leq m\),使得第 \(x_1\) 的第 \(y_0\) 到第 \(y_1\) 、第 \(x_2\) 的第 \(y_0\) 到第 \(y_2\) 以及第 \(y_0\) 的第 \(x_1\) 到第 \(x_3\) 不为土坑,且只在上述这些位置上种花。

\(Subtask: n \leq 500\)

先考虑C形,发现当两横线位置固定时,竖线位置是固定的。所以只需关心横线对答案的贡献

横线对答案的贡献等于两横线长度之积,怎么快速求出每个点往右能延伸的最大长度呢?每一行从右往左做后缀和即可,预处理可以在 \(O(N^2)\) 内完成

考虑 \(O(N^3)\) 统计答案:

第一层循环枚举列数 \(j\)

第二层枚举上方横线所在行号 \(i\)

第三层枚举下方横线所在行号 \(k\)

记 \(r_{i,j}\) 表示点 \((i,j)\) 能向右延伸的最大长度,则有

\[ansc=\sum_{j=1}^{m}\sum_{i=1}^{n}\sum_{k=i+2}^{n}(r_{i,j}-1) \times (r_{k,j}-1)
\]

那F形呢?发现就是在C的基础上在竖线下方加一截。

记 \(c_{i,j}\) 表示 \((i,j)\) 能向下延伸的最大长度,同样可以预处理后缀和,则有

\[ansc=\sum_{j=1}^{m}\sum_{i=1}^{n}\sum_{k=i+2}^{n}(r_{i,j}-1) \times (r_{k,j}-1) \times (c_{k,j}-1)
\]

时间复杂度 \(O(TN^3)\) ,加上输出0的特判,期望得分67pts,但好像CCF数据太水,T根本没有5,所以实际得分75pts。

正解: $ n \leq 1000$

考虑怎么优化到 \(O(N^2)\) 或者 \(O(N^2logN)\) 。

发现固定 \(i,j\) 后, 涉及\(k\) 的部分可以进一步处理成前缀和。

所以记 \(sr_{i,j}\) 表示 \(\sum_{k=i}^{n} r_{k,j}-1\) ,\(ssr_{i,j}\) 表示 \(\sum_{k=i}^{n} (r_{k,j}-1) \times (c_{k,j}-1)\)

注意做的也是后缀和而不是前缀

然后就只需要枚举 \(i,j\) 即可,时间复杂度 \(O(N^2)\) , 期望得分100pts

#include<bits/stdc++.h>
#define F(i,l,r) for(int i=l;i<=r;++i)
#define G(i,r,l) for(int i=r;i>=l;--i)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
const int N=1010;
const ll mod=998244353;
int n,m,vc,vf,t,id;
char ch[N][N];
ll ansf,ansc,r[N][N],c[N][N],sr[N][N],ssr[N][N];
int main(){
// freopen("plant.in","r",stdin);
// freopen("plant.out","w",stdout);
scanf("%d%d",&t,&id);
while(t--){
ansf=0,ansc=0,mem(r),mem(c),mem(sr),mem(ssr),mem(ch);
scanf("%d%d%d%d",&n,&m,&vc,&vf);
F(i,1,n) scanf("%s",ch[i]+1);
if(!vc && !vf){ puts("0 0"); continue; }
F(i,1,n) G(j,m,1) ch[i][j]=='1'?r[i][j]=0:r[i][j]=r[i][j+1]+1;
F(j,1,m) G(i,n,1) ch[i][j]=='1'?c[i][j]=0:c[i][j]=c[i+1][j]+1;
F(j,1,m) G(i,n,1) {
if(ch[i][j]=='1') continue;
sr[i][j]=r[i][j]-1,ssr[i][j]=(r[i][j]-1)*(c[i][j]-1)%mod;
if(ch[i+1][j]=='0' && i+1<=n) sr[i][j]=(sr[i][j]+sr[i+1][j])%mod,ssr[i][j]=(ssr[i][j]+ssr[i+1][j])%mod;
}
F(j,1,m){
F(i,1,n-2){
if(r[i][j]<=1 || ch[i+1][j]=='1' || ch[i+2][j]=='1') continue;
ansc=(ansc+(r[i][j]-1)*sr[i+2][j]%mod)%mod;
ansf=(ansf+(r[i][j]-1)*ssr[i+2][j]%mod)%mod;
}
}
printf("%lld %lld\n",vc?ansc:0,vf?ansf:0);
}
return 0;
}

题解:「NOIP2022 提高组」种花的更多相关文章

  1. 「洛谷P1080」「NOIP2012提高组」国王游戏 解题报告

    P1080 国王游戏 题目描述 恰逢 \(H\)国国庆,国王邀请\(n\)位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 \( ...

  2. 【题解】NOIP2016提高组 复赛

    [题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...

  3. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  4. 【题解】NOIP2017 提高组 简要题解

    [题解]NOIP2017 提高组 简要题解 小凯的疑惑(数论) 不讲 时间复杂度 大力模拟 奶酪 并查集模板题 宝藏 最优解一定存在一种构造方法是按照深度一步步生成所有的联通性. 枚举一个根,随后设\ ...

  5. 【题解】NOIP2016 提高组 简要题解

    [题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...

  6. [题解+总结]NOIP2013-2014提高组题目浅析

    1.前言 迎接NOIP的到来...在这段闲暇时间,决定刷刷水题.这里只是作非常简单的一些总结. 2.NOIP2014 <1> 生活大爆炸之石头剪刀布(模拟) 这是一道考你会不会编程的题目. ...

  7. 【华容道】题解(NOIP2013提高组day2)

    分析 这道题很容易想到令f[x][y][x1][y1]表示空白块在(x,y).指定棋子在(x1,y1)时的最少步数,让空白块和四周的棋子交换,当空白块要和指定棋子交换时,把指定棋子移动,搞一下BFS就 ...

  8. 题解 P1850 [NOIP2016 提高组] 换教室

    做完这道题才略微感觉自己懂了一点关于概率与期望的知识QAQ... 一:关于概率与期望的定义 转载节选于blog 1.什么是数学期望? 数学期望亦称期望.期望值等.在概率论和统计学中,一个离散型随机变量 ...

  9. 题解 「BZOJ4919 Lydsy1706月赛」大根堆

    题目传送门 题目大意 给出一个 \(n\) 个点的树,每个点有权值,从中选出一些点,使得满足大根堆的性质.(即一个点的祖先节点如果选了那么该点的祖先节点的权值一定需要大于该点权值) 问能选出来的大根堆 ...

  10. 题解 「BJOI2018 治疗之雨」

    题目传送门 题目大意 有一个初始为 \(p\) 的数,每次操作分为以下两个: 有 \(\frac{1}{m+1}\) 的概率$+1,但是中途 \(p\) 的最大值只能为 \(n\)$ 有 \(k\) ...

随机推荐

  1. 微服务全链路跟踪:grpc集成zipkin

    微服务全链路跟踪:grpc集成zipkin 微服务全链路跟踪:grpc集成jaeger 微服务全链路跟踪:springcloud集成jaeger 微服务全链路跟踪:jaeger集成istio,并兼容u ...

  2. 增删demo中,React开发中,Vue思维导致的踩坑

    .push等操作,无法监听数据的更新,必须使用setState() state最好写在构造函数中,这是个好习惯 不要什么状态的获取都放在didmount,构造函数里面获取状态也是一个不错的选择

  3. MSI Afterburner 使用

    MSI Afterburner 是一款显卡超频软件,同时可以监测硬件运行数据(CPU 温度.GPU 温度.帧率.帧生成时间等).与其捆绑安装的 RivaTuner Statistics Server ...

  4. 【Jenkins】之自动化测试持续集成

    一.创建jenkins项目 选择节点 创建指定名称的目录名: 写命令,执行shell: 命令填写: # 引入电脑配置文件 #. ~/.bash_profile cd Python_Interface ...

  5. 设计模式 | 中介者模式/调停者模式(Mediator)

    定义: 用一个中介对象来封装以系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地变化他们之间的交互. 结构:(书中图,侵删) 一个抽象中介者 若干具体中介者 一个抽象 ...

  6. iptables 工作过程整理

    转载注明出处: 1.概念和工作原理 iptables是Linux系统中用来配置防火墙的命令.iptables是工作在TCP/IP的二.三.四层,当主机收到一个数据包后,数据包先在内核空间处理,若发现目 ...

  7. 设线性表中每个元素有两个数据项k1和k2,现对线性表按一下规则进行排序:先看数据项k1,k1值小的元素在前,大的在后;在k1值相同的情况下,再看k2,k2值小的在前,大的在后。满足这种要求的

    题目: 设线性表中每个元素有两个数据项k1和k2,现对线性表按一下规则进行排序:先看数据项k1,k1值小的元素在前,大的在后:在k1值相同的情况下,再看k2,k2值小的在前,大的在后.满足这种要求的排 ...

  8. 安卓系统使用chrome插件(以yandex安装油猴为例)

    以tampermonkey为代表的Chrome插件广受好评,但由于Chrome在安卓系统并不支持令人遗憾.所以带来安卓手机使用Chrome插件的教程. 一,首先下载安卓开源浏览器(个人推荐yandex ...

  9. C++: 如何高效地往unordered_map中插入key-value

    C++: unordered_map 花式插入key-value的5种方式 前言 无意中发现std::unordered_map.std::map等插入key-value对在C++17后竟有了 ins ...

  10. JavaScript – Proxy

    参考 阮一峰 – Proxy 介绍和使用 Proxy 的作用是代理对象, 消费者不直接使用对象, 而是使用代理对象. 一般上做代理的目的就是想拦截对象访问做一些别的事情. 比如当对象改变以后, 同步 ...