简要题意

\(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\) 型图案就可以求出来了:

\[\sum_{k=i+2}^{i+d_{i,j}}r_{i,j}r_{k,j}
\]

解释:左下角为 \((i,k)\)。下限加 \(2\) 因为竖长最少为 \(1\)。求和的式子运用了乘法原理。

\(F\) 型图案只比 \(C\) 多了下面那一竖。我们也可以方便的推出式子:

\[\sum_{k=i+2}^{i+d_{i,j}}r_{i,j}r_{k,j}d_{k,j}
\]

这样子暴力算是 \(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] 种花的更多相关文章

  1. P1834 种花小游戏

    我只是想做壮鸭低劈啊,为什么只有状压没有DP-- 原题: 植物大战僵尸这款游戏中,还有个特别有意思的赚钱方式--种花(能长金币的花).种出来的金币需要玩家点击才能得到,或者,玩家可以购买一只蜗牛来帮助 ...

  2. 605. Can Place Flowers种花问题【leetcode】

    Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, ...

  3. 【LeetCode】数组-3(605)-种花问题( 1 的两侧不能有 1 )

    开始的思路:首先统计需要种几只花,用花的数目统计连续 0 的个数.... ...[囧]突然觉得情况有点复杂啊,有连续的又有分散的怎么能统计全呢? 好吧这里喔偷偷的瞄了一眼参看答案... ...(就一眼 ...

  4. 种花 [JZOJ4726] [可撤销贪心]

    Description 经过三十多个小时的长途跋涉,小Z和小D终于到了NOI现场——南山南中学.一进校园,小D就被花所吸引了(不要问我为什么),遍和一旁的种花园丁交(J)流(L)了起来. 他发现花的摆 ...

  5. CDOJ 1292 卿学姐种花 暴力 分块 线段树

    卿学姐种花 题目连接: http://acm.uestc.edu.cn/#/problem/show/1292 Description 众所周知,在喵哈哈村,有一个温柔善良的卿学姐. 卿学姐喜欢和她一 ...

  6. Leetcode 605.种花问题

    种花问题 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表 ...

  7. LeetCode 605. 种花问题(Can Place Flowers) 6

    605. 种花问题 605. Can Place Flowers 题目描述 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. ...

  8. [noip模拟]种花<快速幂+结论>

    描述: OI太可怕了,我决定回家种田.我在后院里开辟了一块圆形的花圃,准备种花.种花是一种艺术,通过一定技术手法,花材的排列组合会让花变得更加的赏心悦目,这就是花艺.当然你知道,我在种田之前是OIer ...

  9. Java实现 LeetCode 605 种花问题(边界问题)

    605. 种花问题 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. 给定一个花坛(表示为一个数组包含0和1,其中0表示没种 ...

  10. LeetCode 605. Can Place Flowers (可以种花)

    Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, ...

随机推荐

  1. Vue学习之---浏览器本地存储(8/17)

    博客园(纯干货):https://www.cnblogs.com/zheng-yuzhu/ 文章目录 1.基础知识 2.代码实例(localStorage.html) 3.测试效果 4.代码实例(se ...

  2. JDK中自带的JVM分析工具

    目录 一.业务背景 二.Jdk-Bin目录 三.命令行工具 1.jps命令 2.jinfo命令 3.jstat命令 4.jstack命令 5.jmap命令 四.可视化工具 1.jconsole 2.v ...

  3. 驱动开发:内核运用LoadImage屏蔽驱动

    在笔者上一篇文章<驱动开发:内核监视LoadImage映像回调>中LyShark简单介绍了如何通过PsSetLoadImageNotifyRoutine函数注册回调来监视驱动模块的加载,注 ...

  4. C# String.IsNullOrEmpty()方法的使用

    IsNullOrEmpty(string)是String类的一个有参的方法,方法需要类的调用,所以String.IsNullOrEmpty(string) IsNullOrEmpty是判断字符串的Nu ...

  5. Transformer 结构分析

    self-attetion 1. 输入 \[X = EmbeddingLookup(X) + PositionalEncoding \\ X.shape == (batch\_size, seq\_l ...

  6. 打地鼠(susliks) 方法记录

    [SDOI2011]打地鼠 题目描述 2020.4.29 数据更新. 打地鼠是这样的一个游戏:地面上有一些地鼠洞,地鼠们会不时从洞里探出头来很短时间后又缩回洞中.玩家的目标是在地鼠伸出头时,用锤子砸其 ...

  7. 解决vue中对象属性改变视图不更新的问题

    在使用VUE的过程中,会遇到这样一种情况, vue data 中的数据更新后,视图没有自动更新. 这个情况一般分为两种, 一种是数组的值改变,在改变数组的值的是时候使用索引值去更改某一项,这样视图不会 ...

  8. linux ip命令

    ip link show # 显示网络接口信息 ip link set eth0 up # 开启网卡 ip link set eth0 down # 关闭网卡 ip link set eth0 pro ...

  9. 【Java并发010】使用层面:发令枪CountDownLatch全解析

    一.前言 CountDownLatch是在java1.5被引入,存在于java.util.cucurrent包中,跟它一起被引入的工具类还有CyclicBarrier.Semaphore.concur ...

  10. [Android开发学iOS系列] TableView展现一个list

    TableView 基础 本文讲讲TableView的基本使用. 顺便介绍一下delegation. TableView用来做什么 TableView用来展示一个很长的list. 和Android中的 ...