CF1178F2 Long Colorful Strip 题解 搜索

这篇具有很好参考价值的文章主要介绍了CF1178F2 Long Colorful Strip 题解 搜索。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Long Colorful Strip

传送门

题面翻译

题目描述

这是 F 题的第二个子任务。F1 和 F2 的区别仅在对于 m m m 和时间的限制上

n + 1 n+1 n+1 种颜色标号从 0 0 0 n n n,我们有一条全部染成颜色 0 0 0 的长为 m m m 的纸带。

Alice 拿着刷子通过以下的过程来给纸带染色:

我们按照从 1 1 1 n n n 的顺序进行染色,进行每次染色时,我们选取一个区间 [ a i , b i ] [a_i,b_i] [ai,bi] 0 ≤ a i < b i ≤ m 0 \le a_i < b_i \le m 0ai<bim,并且这个区间内必定是单种颜色。

染色到最后,纸带上有各种颜色除了颜色 0 0 0。给出纸带最终的状态,问有多少种不同的染色方案能到达最终状态。输出时结果模 998244353 998244353 998244353

输入格式

第一行有两个整数 n n n m m m 1 ≤ n ≤ 500 1 \le n \le 500 1n500 n ≤ m ≤ 1 0 6 n \le m \le 10^6 nm106 n n n 代表除了颜色 0 0 0 有多少种颜色, m m m 代表纸带的长度。

第二行有 m m m 个用空格分隔的整数 c 1 , c 2 , … , c m c_1,c_2,\dots,c_m c1,c2,,cm 1 < = c i < = n 1<=c_i<=n 1<=ci<=n,代表完成染色后纸带的最终状态。保证最终状态中能在纸带上找到从 1 1 1 n n n 所有的颜色。

输出格式

输入一个单独的整数,即 Alice 可行的染色方案数模 998244353 998244353 998244353

题目描述

This is the second subtask of problem F. The only differences between this and the first subtask are the constraints on the value of m m m and the time limit. It is sufficient to solve this subtask in order to hack it, but you need to solve both subtasks in order to hack the first one.

There are n + 1 n+1 n+1 distinct colours in the universe, numbered 0 0 0 through n n n . There is a strip of paper m m m centimetres long initially painted with colour 0 0 0 .

Alice took a brush and painted the strip using the following process. For each i i i from 1 1 1 to n n n , in this order, she picks two integers 0 ≤ a i < b i ≤ m 0 \leq a_i < b_i \leq m 0ai<bim , such that the segment [ a i , b i ] [a_i, b_i] [ai,bi] is currently painted with a single colour, and repaints it with colour i i i .

Alice chose the segments in such a way that each centimetre is now painted in some colour other than 0 0 0 . Formally, the segment [ i − 1 , i ] [i-1, i] [i1,i] is painted with colour c i c_i ci ( c i ≠ 0 c_i \neq 0 ci=0 ). Every colour other than 0 0 0 is visible on the strip.

Count the number of different pairs of sequences { a i } i = 1 n \{a_i\}_{i=1}^n {ai}i=1n , { b i } i = 1 n \{b_i\}_{i=1}^n {bi}i=1n that result in this configuration.

Since this number may be large, output it modulo 998244353 998244353 998244353 .

输入格式

The first line contains a two integers n n n , m m m ( 1 ≤ n ≤ 500 1 \leq n \leq 500 1n500 , n ≤ m ≤ 1 0 6 n \leq m \leq 10^6 nm106 ) — the number of colours excluding the colour 0 0 0 and the length of the paper, respectively.

The second line contains m m m space separated integers c 1 , c 2 , … , c m c_1, c_2, \ldots, c_m c1,c2,,cm ( 1 ≤ c i ≤ n 1 \leq c_i \leq n 1cin ) — the colour visible on the segment [ i − 1 , i ] [i-1, i] [i1,i] after the process ends. It is guaranteed that for all j j j between 1 1 1 and n n n there is an index k k k such that c k = j c_k = j ck=j .

输出格式

Output a single integer — the number of ways Alice can perform the painting, modulo 998244353 998244353 998244353 .

样例 #1

样例输入 #1

3 3
1 2 3

样例输出 #1

5

样例 #2

样例输入 #2

2 3
1 2 1

样例输出 #2

1

样例 #3

样例输入 #3

2 3
2 1 2

样例输出 #3

0

样例 #4

样例输入 #4

7 7
4 5 1 6 2 3 7

样例输出 #4

165

样例 #5

样例输入 #5

8 17
1 3 2 2 7 8 2 5 5 4 4 4 1 1 6 1 1

样例输出 #5

20

提示

In the first example, there are 5 5 5 ways, all depicted in the figure below. Here, 0 0 0 is white, 1 1 1 is red, 2 2 2 is green and 3 3 3 is blue.

CF1178F2 Long Colorful Strip 题解 搜索,题解,c++,算法,c语言

Below is an example of a painting process that is not valid, as in the second step the segment 1 3 is not single colour, and thus may not be repainted with colour 2 2 2 .

CF1178F2 Long Colorful Strip 题解 搜索,题解,c++,算法,c语言

In the second example, Alice must first paint segment 0 3 with colour 1 1 1 and then segment 1 2 with colour 2 2 2 .

解题思路

前言

Luogu居然没有搜索题解,这对萌新十分不友好,所以就由本人来贡献一篇搜索题解吧。

作者建议

该题为这题的进阶版,建议先完成这题再完成本题。

正文

本题有 n < m n<m n<m 的情况,所以与 Short 版解法略有不同。( Short 版做法戳这里)

先将 c c c 数组去重,将连续的一段相同颜色并做一格,便于处理。相关代码如下:

for (int i = 1; i <= m; i++) {
	x = rd();
	if (x != a[len]) {
		a[++len] = x;
	}
}
对于 n = m n=m n=m 的情况:

与 Short 版处理方法相同。

对于 n < m n<m n<m 的情况:
  • 记录下进过前文所描述的去重操作后数组长度,若大于 2 × n 2 \times n 2×n 则一定无解,输出 0 ,并结束程序(否则会 RE ,本人亲测有效)。
  • 在 dfs 函数中,要进行一些改动。
    • 首先,要记录该区间编号最小的颜色在整个数组中第一次与最后一次出现的位置。若其中一个不在该区间内,则该区间无符合条件的涂色方法。

    • 对于符合条件的区间,进行如下操作(为了便于讲解,先放张图):
      CF1178F2 Long Colorful Strip 题解 搜索,题解,c++,算法,c语言

      • 对于该区间编号最小颜色第一次出现位置前于最后一次出现后的部分(红色部分),仍然照 Short 版操作:
      for (int i = l; i <= minid; i++) {
      	tmp1 = (tmp1 + dfs(l, i - 1) * dfs(i, minidl - 1) % Mod) % Mod;
      }
      for (int i = minid; i <= r; i++) {
      	tmp2 = (tmp2 + dfs(minidr + 1, i) * dfs(i + 1, r) % Mod) % Mod;
      }
      tong[l][r] = tmp1 * tmp2 % Mod;
      
      • 对于编号最小颜色出现位置的相隔部分(蓝色部分) ,继续放入 dfs 函数中处理,根据乘法原理,将它与 t o n g l , r tong_{l,r} tongl,r 相乘,就是该区间的方案数了。相关代码片段:
        for (int i = l; i <= r; i++) {
        	if (a[i] == a[minid]) {
        		if (top) {
        			tong[l][r] = (tong[l][r] * (dfs(top + 1, i - 1) % Mod)) % Mod;
        		}
        		top = i;
        	}
        }
      
  • 最后, t o n g 1 , l e n tong_{1,len} tong1,len 就是最终总方案数了。

AC Code

#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int rd() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-')f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void write(int x) {
	if (x < 0)x = ~x + 1, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
const int Mod = 998244353;
const int Maxn = 2200 + 5, Maxm = 2e6 + 5;
int n, m, a[Maxm];
bool vis[Maxm];
int tong[Maxn][Maxn]/*区块l~r的方案数*/, minid, L[Maxm], R[Maxm];
inline int dfs(int l, int r) {
	if (tong[l][r] != -1) {
		return tong[l][r];
	} else if (l >= r) {
		return tong[l][r] = 1;
	} else {
		int minid = l, tmp1 = 0, tmp2 = 0, top = 0, minidl, minidr;
		for (int i = l; i <= r; i++) {//求当前区块编号最小颜色
			if (a[i] < a[minid]) {
				minid = i;
			}
		}
		minidl = L[a[minid]];
		minidr = R[a[minid]];
		if (!(l <= minidl && r >= minidr) && !(r <  minidl && l > minidr)) {
			return tong[l][r] = 0;
		}
		for (int i = l; i <= minid; i++) {
			tmp1 = (tmp1 + dfs(l, i - 1) * dfs(i, minidl - 1) % Mod) % Mod;
		}
		for (int i = minid; i <= r; i++) {
			tmp2 = (tmp2 + dfs(minidr + 1, i) * dfs(i + 1, r) % Mod) % Mod;
		}
		tong[l][r] = tmp1 * tmp2 % Mod;
		for (int i = l; i <= r; i++) {
			if (a[i] == a[minid]) {
				if (top) {
					tong[l][r] = (tong[l][r] * (dfs(top + 1, i - 1) % Mod)) % Mod;
				}
				top = i;
			}
		}
		return tong[l][r];
	}
}
inline void work() {
	memset(tong, -1, sizeof(tong));
	int len = 0, tmp, x;
	n = rd();
	m = rd();
	for (int i = 1; i <= m; i++) {
		x = rd();
		if (x != a[len]) {
			a[++len] = x;
		}
	}
	if (len > 2 * n) {
		cout << 0 << endl;
		return;
	}
	for (int i = 1; i <= len; i++) {
		R[a[i]] = i;
	}
    for (int i = len; i >= 1; i--) {
		L[a[i]] = i;
	}
	for (int i = 1; i <= len; i++) {
		tong[i][i] = L[a[i]] == i && R[a[i]] == i;
	}
	dfs(1, len);
	write(tong[1][len] % Mod);
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	work();
	return 0;
}

不会就问问它(曾经的特邀嘉宾)文章来源地址https://www.toymoban.com/news/detail-791139.html

到了这里,关于CF1178F2 Long Colorful Strip 题解 搜索的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CF1011A Stages 题解

    题目意思: 给你一个长度为 n n n 的字符串 a a a ,在这个字符串中选一个长度为 k k k 的好串(好串标准是啥自己去题目里看吧),问这个好串的最小价值是多少。 思路: 贪心。 首先我们将字符串 a a a 里面的字符进行排序。 因为要最小的价值,所以排好序后的 a a a 的第一个

    2024年02月12日
    浏览(31)
  • 洛谷 CF1743APassword 题解

    https://www.luogu.com.cn/problem/CF1743A 已知一个长度为四的,只包含字符 0 , 1 , 2 , … , 9 0,1,2,dots ,9 0 , 1 , 2 , … , 9 的字符串中不会出现哪些字符,求可能的字符串的数量。 Monocarp has forgotten the password to his mobile phone. The password consists of $ 4 $ digits from $ 0 $ to $ 9 $ (note that it can start wit

    2023年04月20日
    浏览(47)
  • CodeForces CF1846G 题解

    CodeForces题目链接 洛谷题目链接 标准答案是状压之后,转化成Dijkstra算法跑最短路。我这里提供一个不一样的思路。 主人公得了病,有部分类型的症状。所有类型症状共有 (n) 种,用长为 (n) 的01串表示是否有那种症状。共有 (m) 种药,吃第 (i) 种药需要花费时间 (t_i) ,

    2024年02月14日
    浏览(39)
  • CF1145G AI Takeover 题解

    人工智能取得了进展。在这一题中,我们考虑的是石头剪刀布游戏。 然而,比赛的前一天晚上有一群人把机器人弄坏了,于是使用一个程序替代。 您需要找到一个策略,使您能够获胜。祝你好运! 为了方便,石头剪刀布分别用三个字符表示: R , P , S 。 本题有 6 个测试点,

    2024年03月26日
    浏览(44)
  • CF338D GCD Table 题解

    你有一个长度为 (k) 的数列 (a) , 询问是否存在 (xin[1,n]~~~yin[1,m]) 使得 (forall i~~~ gcd(x,y+i-1)=a_i) 。 我们转换一下可以得到: [forall i ~~left{ begin{matrix}xequiv 0pmod{a_i} \\\\y+i-1equiv 0pmod{a_i}end{matrix}right.] 前面一个 (x) 很好解决,直接 最大公倍数 。 (y) 可以转化一下:

    2024年02月07日
    浏览(38)
  • CF963B Destruction of a Tree 题解

      洛谷题目链接   这里提供一个较为朴素的 DP 想法。   给定一棵树,节点个数不超过 (2 times 10^5) ,每次可以删掉度数为偶数的点。问最后能不能删完;能删完给出删除方案。   首先可以随便选一个点作为根。   其次,我们考虑在一棵子树的删除情况,我们令

    2024年02月08日
    浏览(38)
  • CF1881F Minimum Maximum Distance 题解 贪心+DFS

    You have a tree with n n n vertices, some of which are marked. A tree is a connected undirected graph without cycles. Let f i f_i f i ​ denote the maximum distance from vertex i i i to any of the marked vertices. Your task is to find the minimum value of f i f_i f i ​ among all vertices. For example, in the tree shown in the example, vertices 2 2 2 , 6 6

    2024年02月22日
    浏览(42)
  • LeetCode算法题解|​ 669. 修剪二叉搜索树​、108. 将有序数组转换为二叉搜索树、​538. 把二叉搜索树转换为累加树​

    题目链接:669. 修剪二叉搜索树 题目描述: 给你二叉搜索树的根节点  root  ,同时给定最小边界 low  和最大边界  high 。通过修剪二叉搜索树,使得所有节点的值在 [low, high] 中。修剪树  不应该  改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关

    2024年02月06日
    浏览(37)
  • LeetCode算法题解(动态规划)|LeetCode343. 整数拆分、LeetCode96. 不同的二叉搜索树

    题目链接:343. 整数拆分 题目描述: 给定一个正整数  n  ,将其拆分为  k  个  正整数  的和(  k = 2  ),并使这些整数的乘积最大化。 返回  你可以获得的最大乘积  。 示例 1: 示例 2: 提示: 2 = n = 58 算法分析: 定义dp数组及下标含义: dp[i]表述正整数i拆分成k个正整数

    2024年02月04日
    浏览(42)
  • AGC004B Colorful Slimes

    题目链接:Colorful Slimes 思路:挺神奇的$dp$ 一个比较显然的结论:最小值的方案中第$2$种操作最多用$n-1$次 证明大概就是一个数用$n-1$次一定会变成另一个数 下面说说$dp$的思路: $dp[i][j]$表示能用最多$j$次第$2$种操作能变成$a_i$的最小值 假设$a_k$所有可以用最多$j$次第$2$种操作

    2024年02月08日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包