首页 > 其他分享 >AtCoder Regular Contest 128 D Neq Neq

AtCoder Regular Contest 128 D Neq Neq

时间:2023-05-03 18:23:44浏览次数:41  
标签:AtCoder Contest ll long maxn 128 Neq mod

洛谷传送门

AtCoder 传送门

考虑把所有 \(a_i = a_{i+1}\) 的位置断开,分别计算然后把方案数乘起来。接下来的讨论假设 \(a_i \ne a_{i+1}\)。

考虑一个 dp,设 \(f_i\) 为 \([1,i]\) 最后剩下的集合的方案数。转移显然是 \(f_i \gets f_i + f_j\),但是需要满足 \((a_j, a_{j+1}, ..., a_i)\) 需要被删至只剩 \((a_j, a_i)\)。

现在问题变成了如何判定 \((a_1, a_2, ..., a_m)\) 可以被删至只剩 \((a_1, a_m)\)。

如果 \(m \le 3\) 一定可行,下面假设 \(m \ge 4\)。

发现只要数组中不同数的个数 \(\ge 3\) 即可。

考虑证明。如果不同数的个数 \(\le 2\) 一定不可行,否则接下来找到 \(a_{i-1}, a_i, a_{i+1}\) 使得它们两两互不相同,如果删去 \(a_i\) 后不同数个数变成 \(2\),那么数组形式一定是 \((x,y,...,x,y,a_i,x,y,...)\)。此时删去 \(a_{i-1}\) 或 \(a_{i+1}\) 即可。否则删去 \(a_i\)。证毕。

知道了这个限制,可以双指针 + 前缀和简单维护。

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

code
// Problem: D - Neq Neq
// Contest: AtCoder - Daiwa Securities Co. Ltd. Programming Contest 2021(AtCoder Regular Contest 128)
// URL: https://atcoder.jp/contests/arc128/tasks/arc128_d
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 200100;
const ll mod = 998244353;

ll n, a[maxn], f[maxn], g[maxn], b[maxn], c[maxn], cnt, m;

inline void add(ll x) {
	cnt += (!c[x]);
	++c[x];
}

inline void del(ll x) {
	--c[x];
	cnt -= (!c[x]);
}

inline ll calc() {
	for (int i = 1, j = 0; i <= m; ++i) {
		f[i] = (i == 1);
		if (i > 1) {
			f[i] = (f[i] + f[i - 1]) % mod;
		}
		if (i > 2) {
			f[i] = (f[i] + f[i - 2]) % mod;
		}
		add(b[i]);
		while (cnt >= 3) {
			del(b[++j]);
		}
		f[i] = (f[i] + g[min(j, max(i - 3, 0))]) % mod;
		g[i] = (g[i - 1] + f[i]) % mod;
	}
	return f[m];
}

void solve() {
	scanf("%lld", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
	}
	ll ans = 1;
	for (int i = 1, j = 1; i <= n; i = (++j)) {
		while (j < n && a[j] != a[j + 1]) {
			++j;
		}
		m = 0;
		for (int k = i; k <= j; ++k) {
			b[++m] = a[k];
		}
		ans = ans * calc() % mod;
		cnt = 0;
		for (int k = i; k <= j; ++k) {
			c[a[k]] = 0;
		}
	}
	printf("%lld\n", ans);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,Contest,ll,long,maxn,128,Neq,mod
From: https://www.cnblogs.com/zltzlt-blog/p/17369488.html

相关文章

  • AtCoder Beginner Contest 242(D,E)
    AtCoderBeginnerContest242(D,E)D(二叉树搜索)D题目大意就是首先给你一个字符串,代表\(S^0\),然后我们可以操作得到\(S^1,S^2\)等等我们可以知道\(S^i\)是拿\(S^(i-1)\)经过一系列替换而来的,因为这个字符串只有三种字符串,\(A,B,C\),这个替换方式就是把\(A\)替换成\(BC\),把\(B\)......
  • AtCoder Regular Contest 125 F Tree Degree Subset Sum
    洛谷传送门AtCoder传送门首先将度数\(-1\)。设\(f_i\)为体积为\(i\)至多能用几个物品凑出来,\(g_i\)为至少。我们现在要证明一个东西:\(x\in[g_i,f_i]\),\((i,x)\)合法。首先若\((s,x)\)合法,那么必须满足\(s-x\in[-z,z-2]\),其中\(z=\sum\limits_{i=1}......
  • AT_abc106_d [ABC106D] AtCoder Express 2 题解
    题目传送门解题思路区间\(dp\)。划分阶段:以左右城市之间的列车数量为阶段。状态表达:设\(f_{i,j}\)为城市\(i\)与城市\(j\)之间的列车数量。状态转移:由图可知,城市\(l\)与城市\(r\)之间的列车数量,就是城市\(l\)与城市\(r-1\)之间的列车数量与城市\(l+1\)与......
  • AtCoder Regular Contest 119 F AtCoder Express 3
    洛谷传送门AtCoder传送门很厉害的题!考虑所有车站已确定,如何求\(0\)到\(n+1\)的最短路。设\(g_{i,0}\)为只考虑\(0\simi\)的点,到\(i\)和它左边第一个\(\text{A}\)的最短路,\(g_{i,1}\)同理。有转移:若\(s_{i-1}=\text{A},s_i=\text{A},g_{i,0}\getsg_{......
  • AtCoder Regular Contest 119 D Grid Repainting 3
    洛谷传送门AtCoder传送门对每个红格的行和列连边,建出二分图。对于二分图中的每个连通块分别考虑。大胆猜测对于每个连通块,我们都能够进行适当的操作,使得只有一行/一列没被操作(显然不能使所有行和列都被操作)。对应的方案就是随便取一棵生成树,把不被染白的那一行/列拎出来当根,然......
  • AtCoder Regular Contest 117 F Gateau
    洛谷传送门AtCoder传送门差分约束算法:给出\(m\)个不等式形如\(x_{a_i}\lex_{b_i}+y_i\),求是否有解。考虑把不等式看成图上的三角不等式\(dis_v\ledis_u+d\),连边\((b_i,a_i,y_i)\),以\(x_i\)最大的位置跑最短路,如果图中有负环就无解。此时求出来的\(dis_i\)......
  • Atcoder Grand Contest 059 E - Grid 3-coloring(转化+思维)
    首先先是一步很猛的操作——将三染色视作构造一个矩阵使得相邻元素相差\(1\)且每个元素\(\bmod3\)的值就等于其颜色。证明是显然的,我们按从上到下从左到右的顺序填数,可以归纳证明,对于一个相邻格子颜色互不相同的矩阵的填数方案,处于斜对角的两个格子上写的数要么差\(2\),要么......
  • AtCoder Regular Contest 122 D XOR Game
    洛谷传送门AtCoder传送门从高到低按位考虑。设当前位有\(k\)个\(1\)。如果\(k\bmod2=0\),这意味着Alice如果选了一个数,Bob可以选相同的数。发现可以分成\((0,0),(1,1)\)两组,递归下去即可。如果\(k\bmod2=1\),意味着答案这一位一定是\(1\)(因为无论如何都不......
  • AtCoder Regular Contest 119 E Pancakes
    洛谷传送门AtCoder传送门感觉挺典的,为啥有2500啊(观察发现,反转序列对\(\sum\limits_{i=1}^{n-1}|a'_i-a'_{i+1}|\)影响不大。具体而言,设反转了\(a_l\sima_r\),记\(s=\sum\limits_{i=1}^{n-1}|a_i-a_{i+1}|\),那么\(s'=s-|a_{l-1}-a_l|-|a_r-a_{r+1}|......
  • AtCoder Regular Contest 117 D Miracle Tree
    洛谷传送门AtCoder传送门第一步就没想到可以考虑化简限制。设所有点按\(E_i\)从小到大排序后顺序是\(p_1,p_2,...,p_n\)。发现只需满足\(E_{p_{i+1}}-E_{p_i}\ge\operatorname{dis}(p_i,p_{i+1})\)。证明是对于任意\(i<j<k\),若\(p_i,p_j\)和\(p_j,p_k\)均满......