首页 > 其他分享 >CF1503E 2-Coloring

CF1503E 2-Coloring

时间:2024-08-16 15:41:22浏览次数:13  
标签:Coloring 重叠 cdot sum int maxn CF1503E 两峰

CF1503E 2-Coloring

题目大意

略过。

做法解析

不会组合,使用了 DP,但其实本质相同。

我们假设所有的格子都是蓝色的,然后考虑将一些格子换成黄色的。

我们考虑从每一行的两头开始将格子换成黄色,只要不把整一行都换成黄色的我们就可以保证每一行恰好有一段蓝色的格子。

为了保证每一列恰好有一段黄色的格子,我们从一头开始替换的黄色格子必须是单峰的,可以有多个最大值,并不严格。

并且两头的峰必须是并集为整一行的,这样才能保证恰好都有一段连续的黄色格子。

见下图(我认为代码块更加清晰):

0 表示蓝色,1 表示黄色。

1 0 0 0 0 0 0 0 0 1
1 1 1 1 0 0 0 0 0 1
1 1 1 1 1 0 0 0 1 1
1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 1 1 1 1 1

并且如果两个峰有重叠部分,那么他们必须是连续在一起的。

例如,这样是不对的,不满足恰有一段连续的黄色。

1 0 0 0 0 0 0 0 0 1
1 1 1 1 0 0 0 0 0 1
1 1 1 1 1 1 1 0 1 1
1 1 0 0 0 0 1 1 1 1
0 0 0 0 0 1 1 1 1 1

但是这样是对的:

1 0 0 0 0 0 0 0 0 1
1 1 1 1 0 0 0 0 0 1
1 1 1 1 1 1 1 0 1 1
1 1 0 0 0 1 1 1 1 1
0 0 0 0 0 1 1 1 1 1

接着我们发现一件事情,对于两种颜色其实他们是等价的,只是把图形旋转九十度来看而已。

我们考虑证明任意一个合法的图形必有一种颜色满足其的两峰没有重叠部分。

证明是简单的,如果其中一种颜色的两峰有重叠部分,那么这两峰必然是连续在一起的,那么对于另一种颜色的两峰恰好就是没有重叠部分的了。

所以我们可以考虑统计一种颜色的两峰恰好没有重叠部分的方案再减去两种颜色同时两峰恰好没有重叠部分的方案,这样就求出了答案。

考虑如何统计一种颜色的两峰恰好没有重叠部分的方案。

枚举两峰位置 \(i\),\(j\),其中一峰高度 \(x\) 那么另一峰高度为 \(m-x\),注意错开 \(i\),\(j\) 的位置,不然就并完一整行了。

由于单峰,我们可以拆成两个钦定不上升的序列的方案数的乘积。

这个如何求呢,可以组合,但是我使用了 DP

设 \(f(i,j)\) 表示最大值为 \(i\) 长度为 \(j\) 的不上升子序列个数。

那么有状态转移方程。

\[f(i,j) = \sum_{k=0}^i f(k,j-1) \]

比较明显的前缀和优化,可以 \(O(n^2)\) 预处理。

现在还有一个问题,由于单峰不是严格的,所以我们就算错开了 \(i\),\(j\) 仍然无法避免他们并完一整行。

我们考虑在前面的峰是最后一个相同的最大值,在后面的峰是第一个相同的最大值,这样就可以巧妙的避免上面的问题了。

总的来说答案等于:

\[\begin{aligned} ans &= \sum_{i=1}^n \sum_{j=i+1}^n \sum_{k=1}^{m-1} 2 \cdot f(k,i-1) \cdot f(k-1,n-1) \cdot f(m-k-1,j-1) \cdot f(m-k,n-j) \\ &= \sum_{i=1}^n \sum_{k=1}^{m-1} 2 \cdot f(k,i-1) \cdot f(k-1,n-1) \cdot \sum_{j=i+1}^n f(m-k-1,j-1) \cdot f(m-k,n-j) \\ \end{aligned} \]

后面的部分可以用后缀和优化。

时间复杂度 \(O(n^2)\)。

对于另外一种颜色,记得交换 \(n\),\(m\)。

接下来减去两种颜色同时恰好没有重叠部分的方案。

这样看起来是一个风车的样子,如下图,图中 I 实际为 \(1\):

1 0 0 0 0 0 1
1 1 1 0 0 0 1 
1 1 1 I 0 0 1
1 1 0 0 1 1 1
1 0 0 0 0 1 1
1 0 0 0 0 0 0 

我们枚举左上角 \((i,j)\)(I 位置),这样的方案数实际为。

\[res = \sum_{i=1}^{n-1} \sum_{j=1}^{m-1} 2 \cdot f(j-1,n-1) \cdot f(m-j-1,i) \cdot f(i-1,j) \cdot f(n-i-1,m-j) \]

时间复杂度 \(O(n^2)\)。

总时间复杂度 \(O(n^2)\)。

后记

赛场想了三个小时的想法,最后因为没有看到最后的后缀和优化遗憾离场。

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
const int maxn=2e3;
int n,m;
int f[maxn+5][maxn+5];
int g[maxn+5][maxn+5];
int h[maxn+5][maxn+5];
int ans;
inline void Init(){
	for(int i=0;i<=maxn;i++){
		f[i][0]=1;
		if(i) g[i][0]=(g[i-1][0]+f[i][0])%mod;
		else g[i][0]=f[i][0];
	}
	for(int j=1;j<=maxn;j++){
		for(int i=0;i<=maxn;i++){
			f[i][j]=g[i][j-1];
			if(i) g[i][j]=(g[i-1][j]+f[i][j])%mod;
			else g[i][j]=f[i][j];
		}
	}
}
inline void Calc(){
	memset(h,0,sizeof(h));
	for(int i=n-1;i>=1;i--){
		for(int k=1;k<m;k++){
			h[i][k]=(h[i+1][k]
				+f[m-k-1][i]*f[m-k][n-i-1]%mod)%mod;
		}
	}
}
inline void Solve(){
	Calc();
	for(int i=1;i<=n;i++){
		for(int k=1;k<m;k++){
			ans=(ans+2*f[k][i-1]%mod
				*f[k-1][n-i]%mod*h[i][k]%mod)%mod;
		}
	}
}
inline void Work(){
	for(int i=1;i<n;i++){
		for(int j=1;j<m;j++){
			ans=(ans-2*f[j-1][n-i]%mod*f[m-j-1][i]%mod
				*f[i-1][j]%mod*f[n-i-1][m-j]%mod)%mod;
		}
	}
}
signed main(){
//	freopen("magic.in","r",stdin);
//	freopen("magic.out","w",stdout);
	Init();
	scanf("%lld%lld",&n,&m);
	Solve();
	swap(n,m);
	Solve();
	Work();
	printf("%lld",(ans%mod+mod)%mod);
	return 0;
}

标签:Coloring,重叠,cdot,sum,int,maxn,CF1503E,两峰
From: https://www.cnblogs.com/DeepSeaSpray/p/18362961

相关文章

  • AT_agc025_b RGB Coloring 题解
    ProblemSolution由于涂绿色的得分为\(A+B\),所以可以将红色与蓝色独立考虑。依次枚举红色的个数,假定为\(i\),所以剩余需要的得分为\(K-i\timesA\),判断是否能被\(B\)整除,若能,则蓝色个数为\(\frac{K-i\timesA}{B}\),设为\(j\),则总方案累加\(C^{i}_{n}\timesC^{j}_{n}\),除......
  • Interactive Game with Coloring
    看这篇题解解释一下,如果存在一个点通向父亲的边和某一条通向儿子的边的颜色相同,那么一开始如果起点就在这个点的话,是没有办法向上走的,所以任意一个点通向父亲的边和某一条通向儿子的边的颜色不同对于非特殊点,我们只要一直走没有重复出现的那个颜色就好了如果某一时刻走到了特殊......
  • D. Coloring Brackets
    原题链接题解首先,假设当前\(s(l,r)\)括号序列为合法序列,则有如下几种情况:\(l+1==r\)()\(match[r]==l\)(...)\(match[r]!=l\)(...)...(...)code#include<bits/stdc++.h>usingnamespacestd;constlonglongMOD=1e9+7;longlongdp[705][705][3][3]......
  • D. Cross Coloring
    原题链接题解设想每一个\(x,y\)代表中控台,中控台颜色改变它控制的颜色也会跟着改变,我们倒过来求,这样就能确保每个中控台有没有控制的颜色code#definelllonglong#include<bits/stdc++.h>usingnamespacestd;constllmod=998244353;llxs[200005]={0};llys[200005]......
  • Coloring Edges
    \(Solution\)link一个经典结论是有向图中的任意一个环总能由一条生成树上的从祖先到儿子的链以及一条返祖边组成,正确性显然。不妨将所有树边和横插边都染成黑色,返祖边染成白色,这样就可以保证任意一个环都有两种颜色了。判断横插边和返祖边可以用栈来维护。#include<bits/std......
  • CF111D Petya and Coloring 题解
    很明显这是一道组合题。首先特判一下,当\(m=1\)时,答案就是\(k^n\)。对于\(m>1\)的情况,我们可以得出一个结论:对于沿格子的线穿过的任何垂直线,会将棋盘分成两个非空的部分,这两个部分中的不同颜色的数量相同且总是不变。设这个不同颜色的数量为\(i\),那么左边这部分的颜色一定......
  • 题解 CF1781G Diverse Coloring
    \(\texttt{link}\)题意给定一棵\(n\)个点的二叉树,现对其每个点染成黑色或白色。一种合法的染色方案满足:对于所有黑色的点,都存在白色的点与之相邻。对于所有白色的点,都存在黑色的点与之相邻。一种染色方案的权值是染成黑色的点数与染成白色的点数之差的绝对值。\(\foral......
  • Codeforces Round 734 (Div. 3)B2. Wonderful Coloring - 2(贪心构造实现)
    思路:分类讨论:当一个数字出现的次数大于等于k,那么最多有k个能被染色,当一个数字出现的次数小于k,南那么这些数字都可能被染色还有一个条件就是需要满足每个颜色的数字个数一样多,这里记出现次数小于k的所有数字的出现次数总和为sum,将所有这些数字排序后,前sum-sum%k个数字是都可以......
  • [Codeforces] CF1774B Coloring
    CF1774BColoring题意Cirno_9baka的纸条上有\(n\)个格子,他觉得空白的纸条看着有点无趣,于是想在纸条的格子上涂上\(m\)种颜色。同时,他认为第\(i\)种颜色必须要用\(a_i\)次,且每连续\(k\)个格子里涂的颜色必须互不相同。Cirno_9baka想知道有没有这样的一种涂色方案能......
  • 题解 CF1887E【Good Colorings】
    萌萌交互题。对网格图进行二分图建模,左部\(n\)个点表示每一行,右部\(n\)个点表示每一列。若格子\((i,j)\)被染成\(c\)色,就连接\((L_i,R_j,c)\)的边。由抽屉原理易证,在初始局面中至少有一个各边颜色均不同的偶环。获胜条件相当于存在一个各边颜色均不同的四元环。讨论......