首页 > 其他分享 >NOIP2022T1题解

NOIP2022T1题解

时间:2022-11-30 23:01:43浏览次数:45  
标签:int 题解 S1 texttt 土坑 leq 种花 NOIP2022T1

[NOIP2022] 种花(民间数据)

题目描述

小 C 决定在他的花园里种出 \(\texttt{CCF}\) 字样的图案,因此他想知道 \(\texttt C\) 和 \(\texttt F\) 两个字母各自有多少种种花的方案;不幸的是,花园中有一些土坑,这些位置无法种花,因此他希望你能帮助他解决这个问题。

花园可以看作有 \(n\times m\) 个位置的网格图,从上到下分别为第 \(1\) 到第 \(n\) 行,从左到右分别为第 \(1\) 列到第 \(m\) 列,其中每个位置有可能是土坑,也有可能不是,可以用 \(a_{i,j} = 1\) 表示第 \(i\) 行第 \(j\) 列这个位置有土坑,否则用 \(a_{i,j} = 0\) 表示这个位置没土坑。

一种种花方案被称为 \(\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\) 不为土坑,且只在上述这些位置上种花。

样例一解释中给出了 \(\texttt{C-}\) 形和 \(\texttt{F-}\) 形种花方案的图案示例。

现在小 C 想知道,给定 \(n, m\) 以及表示每个位置是否为土坑的值 \(\{a_{i,j}\}\),\(\texttt{C-}\) 形和 \(\texttt{F-}\) 形种花方案分别有多少种可能?由于答案可能非常之大,你只需要输出其对 \(998244353\) 取模的结果即可,具体输出结果请看输出格式部分。

对于所有数据,保证:\(1 \leq T \leq 5\),\(1 \leq n, m \leq 10^3\),\(0 \leq c, f \leq 1\),\(a_{i,j} \in \{0, 1\}\)。

题解

观察数据范围,考虑\(O(nm)\)求解,我们发现,\(F\)型就是\(C\)型扩展,考虑先求解\(C\)型

因为\(C\)型涉及到了三段\(0\),并且一个足够大的\(C\)能够通过上下两段的收缩来得到其他的合法方案,考虑对于枚举左上角,求解出合法的\(C\)

可以这样考虑,对于每一个左上角,需要往右和往下伸展,那么不妨用\(O(nm)\)的小\(DP\)求解出每一个点往右和往下最多伸展多少。由于这个\(C\)要求段的长度不能小于\(2\),而一个\(C\)型如果确定了竖着的一段,那么横着的那两段,设最长为\(x_1,x_2\)那么每一段都可以从\(2\)取到最大值构成合法的\(C\),总方案数就是\((x_1-1)(x_2-1)\),考虑直接在这个长度减一

设\(S1_{x,y},S2_{x,y}\)分别表示点\((x,y)\)向左和向下最长段的长度\(-1\),可以采用如下\(DP\)

	//预处理S1
		for(int y=1;y<=m;y++){
			for(int x=n;x;--x){
				if(a[x][y]==1)s2[x][y]=-1;
				else s2[x][y]=s2[x+1][y]+1;
			}
		}
	//预处理S2
		for(int x=1;x<=n;x++){
			for(int y=m;y;--y){
				if(a[x][y]==1)s1[x][y]=-1;
				else s1[x][y]=s1[x][y+1]+1;
			}
		} 

那么考虑如何才能对一个点求出所有合法的\(C\),容易想到,总方案数中的\(x_1\)是确定的,我们可以将所有的\(x_2\)加上,很简单,再搞一个前缀和即可,设这个前缀和为\(S3\)

接着扩展到\(F\),\(F\)本质上是对\(C\)进行的扩展,可以求出一个\(C\)最多向下扩展多少,这就是这个\(C\)能够向下组合出\(F\)的总方案数,可以进行维护,就是再做一个前缀和\(S4\),\(S4_{x,y}\)即为对于\((x,y)\)向下扩展的每一个数的\(S2,S1\)的乘积,这样最终的答案即为

\[Ans_{C}=\sum_{x=1}^n\sum_{y=1}^m[a[x,y]\neq 1]S1[x,y]\times S3[x+2,y] \]

\[Ans_{F}=\sum_{x=1}^n\sum_{y=1}^m[a[x,y]\neq 1]S1[x,y]\times S4[x+2,y] \]

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 1050
#define p 998244353
int n,m,f1,f2,a[N][N],s1[N][N],s2[N][N],s3[N][N],s4[N][N],T,id;
int main(){
	ios::sync_with_stdio(false);
	cin>>T>>id;
	while(T--){
		memset(s1,-1,sizeof s1);
		memset(s2,-1,sizeof s2);
		memset(s3,0,sizeof s3);
		memset(s4,0,sizeof s4);
		cin>>n>>m>>f1>>f2;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				char x;
				cin>>x;
				a[i][j]=x-'0';
			}
		}
	//预处理S1
		for(int y=1;y<=m;y++){
			for(int x=n;x;--x){
				if(a[x][y]==1)s2[x][y]=-1;
				else s2[x][y]=s2[x+1][y]+1;
			}
		}
	//预处理S2
		for(int x=1;x<=n;x++){
			for(int y=m;y;--y){
				if(a[x][y]==1)s1[x][y]=-1;
				else s1[x][y]=s1[x][y+1]+1;
			}
		} 
	//预处理S3
		for(int y=1;y<=m;y++){
			for(int x=n;x;--x){
				if(a[x][y]==1)s3[x][y]=0;
				else s3[x][y]=s3[x+1][y]+s1[x][y];
			}
		}
	//预处理S4
		for(int y=1;y<=m;y++){
			for(int x=n;x;--x){
				if(a[x][y]==1)s4[x][y]=0;
				else s4[x][y]=(1ll*s4[x+1][y]+1ll*s1[x][y]*s2[x][y])%p;
			}
		} 
	//
		int ans1=0,ans2=0;
		for(int x=1;x<=n-2;x++){
			for(int y=1;y<=m;y++){
				if(a[x][y]==1)continue;
				ans1=(1ll*ans1+1ll*s1[x][y]*s3[x+2][y]*(a[x+1][y]!=1)%p)%p;
				ans2=(1ll*ans2+1ll*s1[x][y]*s4[x+2][y]*(a[x+1][y]!=1)%p)%p;
			}
		}
		cout<<1ll*ans1*f1%p<<" "<<1ll*ans2*f2%p<<endl;
	}
} 

标签:int,题解,S1,texttt,土坑,leq,种花,NOIP2022T1
From: https://www.cnblogs.com/oierpyt/p/16940094.html

相关文章

  • P6007题解
    P6007[USACO20JAN]SpringboardsG题目描述Bessie在一个仅允许沿平行于坐标轴方向移动的二维方阵中。她从点\((0,0)\)出发,想要到达\((N,N)\)(\(1\leqN\leq10^9\))......
  • P3514题解
    给一个只有1和2的序列,每次询问有没有一个子串的和为xSPJ对于格式的要求较为严格。对于每个询问后,应紧跟一个换行符。在最后一次输出你的答案以及一个换行符后不应有任何输......
  • 道路游戏——题解
    单调队列优化-道路游戏[NOIP2009普及组]道路游戏题目描述小新正在玩一个简单的电脑游戏。游戏中有一条环形马路,马路上有\(n\)个机器人工厂,两个相邻机器人工厂之间......
  • 题解——红黑树
    进制运算-红黑树题目描述红黑树是一类特殊的二叉搜索树,其中每个结点被染成红色或黑色。若将二叉搜索树结点中的空指针看作是指向一个空结点,则称这类空结点为二叉搜索树的......
  • 题解——GCD
    给定正整数\(n\),求\(1\lex,y\len\)且\(\gcd(x,y)\)为素数的数对\((x,y)\)有多少对。\(n\le10^7\)题解做法1题意即为求\(S=\sum_{质数p|n}\sum_{i=1}^n\sum_{......
  • 题解——阿狸与桃子的游戏
    边权均分-巧妙的阿狸和桃子的游戏[国家集训队]阿狸和桃子的游戏题目描述阿狸和桃子正在玩一个游戏,游戏是在一个带权图G=(V,E)上进行的,设节点权值为w(v),边权为c(e)。游......
  • 分组——题解
    分组题目背景大样例可在页面底部「附件」中下载。题目描述小C在了解了她所需要的信息之后,让兔子们调整到了恰当的位置。小C准备给兔子们分成若干个小组来喂恰当的......
  • KDOI-3还原数据题解
    「KDOI-03」还原数据题目描述小E正在做一道经典题:给定一个长度为\(n\)的序列\(a\)和\(q\)个操作,操作共有\(2\)种类型:\(\tt{1~l~r~x}\):对于所有\(l\lei\le......
  • 题解——星之界
    题解考虑化简这个可恶的式子\[\prod\limits_{i=l}^{r}C_{\sum_{j=l}^{i}a_j}^{a_i}\]拆开,设\(S\)为前缀和数组\[=\prod^r_{i=l}\frac{(S_i-S_{l-1})!}{a_i!(S_i-S......
  • P8858题解
    折线题目描述平面直角坐标系的第一象限内有一块左下角为\((0,0)\)右上角为\((10^{100},10^{100})\)的矩形区域,区域内有正偶数个整点,试求出这样一条从\((0,0)\)出发......