P8865 [NOIP2022] 种花
简要题意
\(T\) 组数据,给你一个 \(n\times m\) 的 \(01\) 矩阵。 \(0\) 部分可以组成 \(A_c\) 个 \(\texttt{C}\) 型图案和 \(A_f\) 个 \(\texttt{F}\) 型图案。你需要输出 \(A_c \times c \bmod 998244353,A_f \times f \bmod 998244353\)。
\(1\leq T \leq 5,1 \leq n,m \leq 10^3,c\in\{0,1\},f\in\{0,1\}\)
思路
纪念考场手切的 NOIP T1。
预处理 \(r_{i,j},d_{i,j}\) 表示向右、向下 \(0\) 可以延申到多少格以外。如:
0010
0000
0001
1010
0111
其中 \(r_{2,2}=2,d_{2,2}=2\).
首先考虑 \(\texttt{C}\) 型图案。由上面一横,中间一竖,下面一横组成。考虑枚举左上角 \((i,j)\),那么以这个点为左上角的 \(C\) 型图案就可以求出来了:
\]
解释:左下角为 \((i,k)\)。下限加 \(2\) 因为竖长最少为 \(1\)。求和的式子运用了乘法原理。
\(F\) 型图案只比 \(C\) 多了下面那一竖。我们也可以方便的推出式子:
\]
这样子暴力算是 \(O(Tn^2m)\) 的,可以获得 \(85\) 分。
考虑优化,上面两个式子把 \(r_{i,j}\) 提出来后直接前缀和优化即可。
这样子时间复杂度是 \(O(Tnm)\),可以通过本题。
代码
// O(nmt)
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,id,n,m,c,f;
int a[1005][1005];
char s[1005];
int rgt[1005][1005],down[1005][1005];
int rdqzh[1005][1005],rgtqzh[1005][1005];
const int mod = 998244353;
inline int M(int x){
return (x%mod+mod)%mod;
}
inline void getrgt(){
for(int i=1;i<=n;i++){
int j=1;
while(j<=m){
if(a[i][j]==0){
int start=j;
for(;j<=m&&a[i][j]==0;j++);
for(int val=0,k=j-1;k>=start;k--,val++){
rgt[i][k]=val;
}
j--;
}
j++;
}
}
}
inline void getdown(){
for(int i=1;i<=m;i++){
int j=1;
while(j<=n){
if(a[j][i]==0){
int start=j;
for(;j<=n&&a[j][i]==0;j++);
for(int val=0,k=j-1;k>=start;k--,val++){
down[k][i]=val;
}
j--;
}
j++;
}
}
}
inline void preworks(){
getrgt();
getdown();
for(int j=1;j<=m;j++){
for(int i=1;i<=n;i++){
// rgtqzh[i][j] is rgt[1][j]+rgt[2][j]+...+rgt[i][j]
rgtqzh[i][j]=M(rgtqzh[i-1][j]+rgt[i][j]);
// rdqzh[i][j] is rgt[1][j]*down[1][j]+rgt[2][j]*down[2][j]+...+rgt[i][j]**down[i][j]
rdqzh[i][j]=M(rdqzh[i-1][j]+M(rgt[i][j]*down[i][j]));
}
}
}
inline int countc(){
int ans=0;
for(int i=1;i<=m;i++){// C's col
for(int j=1;j<=(n-2);j++){ // C's top row
if((j+2)>(j+down[j][i]))continue;
ans = M(ans+M(rgt[j][i]*M(rgtqzh[j+down[j][i]][i]-rgtqzh[j+2-1][i])));
// int pans=0;
// for(int k=j+2;k<=(j+down[j][i]);k++){// C's bottom row
// pans=pans+(rgt[k][i])%mod;
// pans%=mod;
// }
// ans=ans+pans*rgt[j][i]%mod;
}
}
return ans;
}
inline int countf(){
int ans=0;
for(int i=1;i<=m;i++){// F's col
for(int j=1;j<=(n-3);j++){// F's top row
if((j+2)>(j+down[j][i]))continue;
ans=M(ans+M(rgt[j][i]*M(rdqzh[j+down[j][i]][i]-rdqzh[j+2-1][i])));
// for(int k=(j+2);k<=(j+down[j][i]);k++){// F's bottom row
// ans=ans+(((rgt[j][i]*rgt[k][i])%mod)*down[k][i])%mod;
// ans%=mod;
// }
}
}
return ans;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#ifndef ZYBAKIOI
freopen("plant.in","r",stdin);
freopen("plant.out","w",stdout);
#endif
cin>>t>>id;
if(id==1){
while(t--)cout<<0<<' '<<0<<'\n';
return 0;
}
while(t--){
memset(rgt,0,sizeof(rgt));
memset(down,0,sizeof(down));
memset(rdqzh,0,sizeof(rdqzh));
memset(rgtqzh,0,sizeof(rgtqzh));
memset(a,0,sizeof(a));
cin>>n>>m>>c>>f;
for(int i=1;i<=n;i++){
cin>>(s+1);
for(int j=1;j<=m;j++){
a[i][j]=s[j]-'0';
}
}
preworks();
cout<<(c*countc())<<' '<<(f*countf())<<'\n';
}
return 0;
}
/*
I hope my grandfathers can give me a good prize in NOIP 2022.
ZYB,YSC,LF,LWX,HZY,ZBZ,YTXY,GRZ,LGS,DZY,WQX
they are my grandfathers,they AKed IOI!(%%%)
And They AK NOIP!
*/
P8865 [NOIP2022] 种花的更多相关文章
- P1834 种花小游戏
我只是想做壮鸭低劈啊,为什么只有状压没有DP-- 原题: 植物大战僵尸这款游戏中,还有个特别有意思的赚钱方式--种花(能长金币的花).种出来的金币需要玩家点击才能得到,或者,玩家可以购买一只蜗牛来帮助 ...
- 605. Can Place Flowers种花问题【leetcode】
Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, ...
- 【LeetCode】数组-3(605)-种花问题( 1 的两侧不能有 1 )
开始的思路:首先统计需要种几只花,用花的数目统计连续 0 的个数.... ...[囧]突然觉得情况有点复杂啊,有连续的又有分散的怎么能统计全呢? 好吧这里喔偷偷的瞄了一眼参看答案... ...(就一眼 ...
- 种花 [JZOJ4726] [可撤销贪心]
Description 经过三十多个小时的长途跋涉,小Z和小D终于到了NOI现场——南山南中学.一进校园,小D就被花所吸引了(不要问我为什么),遍和一旁的种花园丁交(J)流(L)了起来. 他发现花的摆 ...
- CDOJ 1292 卿学姐种花 暴力 分块 线段树
卿学姐种花 题目连接: http://acm.uestc.edu.cn/#/problem/show/1292 Description 众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一 ...
- Leetcode 605.种花问题
种花问题 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表 ...
- LeetCode 605. 种花问题(Can Place Flowers) 6
605. 种花问题 605. Can Place Flowers 题目描述 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. ...
- [noip模拟]种花<快速幂+结论>
描述: OI太可怕了,我决定回家种田.我在后院里开辟了一块圆形的花圃,准备种花.种花是一种艺术,通过一定技术手法,花材的排列组合会让花变得更加的赏心悦目,这就是花艺.当然你知道,我在种田之前是OIer ...
- Java实现 LeetCode 605 种花问题(边界问题)
605. 种花问题 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种 ...
- LeetCode 605. Can Place Flowers (可以种花)
Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, ...
随机推荐
- 安装notepad++ 安装Python Python环境变量的数值。怎样在notepad++上运行Python的代码
文章目录 1.下载安装一个Python的编辑器notepad++,(我这里有现成的,也可以去网上搜很多) 2.安装python,(我这里有现成的,也可以去网上下载). 3.怎样彻底删除Python,有 ...
- DevOps | 如何快速提升团队软件开发成熟度,快速提升研发效能?
今天一个小伙伴问我,如何「快速提升」一个团队的软件开发成熟度?我犯难了.我个人理解一个团队的软件开发成熟度涉及的东西很多,但最简单最直接的方法就是发钱涨工资,可是估计很多公司不愿意,那就只有扣了. 快 ...
- SQL---ltrim()和rtrim()函数的使用
背景 去除字符串首尾空格大家肯定第一个想到trim()函数,不过在sqlserver中是没有这个函数的,却而代之的是ltrim()和rtrim()两个函数. 看到名字所有人都 知道做什么用的了,ltr ...
- Ubuntu安装Docker及镜像加速器
一.安装Docker sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificate ...
- Android开发之线程间通信
Android开发之线程间通信 当我们的软件启动的时候,计算机会分配进程给到我们运行的程序,在进程中包含多个线程用于提高软件运行速度. 在android网络请求中,我们知道在日常开发中不能在子线程中跟 ...
- linux常用指令记录
给目标文件夹执行权限:chmod -R 777 html du -sh . [对当前目录下所有的目录和文件的大小进行汇总,-s表示汇总,-h表示以KB, MB, GB, TB格式进行人性化显示]du ...
- C++使用ODBC连接数据库遇到的问题
C++使用ODBC连接数据库遇到的问题 1.SQL语句中包含中文无法正常执行的问题 2.字符与宽字符相互转化的问题 C++使用ODBC连接数据库遇到的问题 1.SQL语句中包含中文无法正常执行的问题 ...
- 【Java SE】Day02 数据类型转换、运算符、方法入门
一.数据类型转换 1.自动转换 取值范围小在运算时会提升为取值范围大的类型 byte+int=int int+double=double 转换规则:byte.short.char-->int-- ...
- K8S 部署电商项目
Ingress 和 Ingress Controller 概述 在 k8s 中为什么会有 service 这个概念?Pod 漂移问题 Kubernetes 具有强大的副本控制能力,能保证在任意副本(P ...
- nvm下升级npm版本
1 3445 error path C:\Users\xxx\AppData\Roaming\nvm\v12.18.3\npm.cmd 2 3446 error Refusing to delete ...