首页 > 其他分享 >AtCoder Beginner Contest 258 Ex Odd Steps

AtCoder Beginner Contest 258 Ex Odd Steps

时间:2023-05-30 22:24:52浏览次数:42  
标签:AtCoder typedef matrix Beginner Contest res bmod long ll

洛谷传送门

AtCoder 传送门

不错的矩阵快速幂优化 dp 练习题。

考虑一个朴素 dp,\(f_i\) 为组成和为 \(i\) 且用到的数都是奇数的方案数。有转移:

\[f_i = \begin{cases} \sum\limits_{j=0}^{i-1} [i \bmod 2 \ne j \bmod 2] f_j & i \notin A \\ 0 & i \in A \end{cases} \]

考虑前缀和优化,设 \(g_{i, j} = \sum\limits_{i=0}^i [i \bmod 2 = j] f_i\),那么:

\[f_i = \begin{cases} g_{i, 1 - i \bmod 2} & i \notin A \\ 0 & i \in A \end{cases} \]

\[g_{i, i \bmod 2} = g_{i - 1, i \bmod 2} + f_i = g_{i - 1, i \bmod 2} + [i \notin A] g_{i - 1, 1 - i \bmod 2} \]

\[g_{i, 1 - i \bmod 2} = g_{i - 1, 1 - i \bmod 2} \]

至此得到了一个 \(O(S)\) 的做法。

发现 \([0, S]\) 被 \(A_i\) 分成若干段,并且每一段的转移方程重复。为了方便把 \(i \bmod 2 = 1, i \bmod 2 = 0\) 的相邻两个 \(i\) 放一起考虑,那么相当于 \(g'_0 = 2g_0 + g_1, g'_1 = g_0 + g_1\)。容易刻画成矩阵形式,然后分段转移。注意处理一些端点奇偶性不相同的情况。

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

code
// Problem: Ex - Odd Steps
// Contest: AtCoder - AtCoder Beginner Contest 258
// URL: https://atcoder.jp/contests/abc258/tasks/abc258_h
// Memory Limit: 1024 MB
// Time Limit: 3000 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 double db;
typedef long double ldb;
typedef pair<ll, ll> pii;

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

ll n, m, a[maxn], f[maxn], g[2];
struct matrix {
	ll a[2][2];
	matrix() {
		mems(a, 0);
	}
} ma, I, ans;

inline matrix operator * (matrix a, matrix b) {
	matrix res;
	for (int i = 0; i < 2; ++i) {
		for (int j = 0; j < 2; ++j) {
			for (int k = 0; k < 2; ++k) {
				res.a[i][j] = (res.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;
			}
		}
	}
	return res;
}

inline matrix qpow(matrix a, ll p) {
	matrix res = I;
	while (p) {
		if (p & 1) {
			res = res * a;
		}
		a = a * a;
		p >>= 1;
	}
	return res;
}

void solve() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
	}
	a[n + 1] = m + 1;
	ma.a[0][0] = 2;
	ma.a[0][1] = ma.a[1][0] = ma.a[1][1] = 1;
	I.a[0][0] = I.a[1][1] = 1;
	ans.a[0][0] = 1;
	for (int i = 1; i <= n + 1; ++i) {
		if (a[i] - a[i - 1] <= 5) {
			for (ll x = a[i - 1] + 1; x < a[i]; ++x) {
				ans.a[0][x & 1] = (ans.a[0][x & 1] + ans.a[0][(x & 1) ^ 1]) % mod;
			}
		} else {
			ll x = a[i - 1] + 1;
			if (x % 2 == 0) {
				ans.a[0][x & 1] = (ans.a[0][x & 1] + ans.a[0][(x & 1) ^ 1]) % mod;
				++x;
			}
			matrix t = qpow(ma, (a[i] - x) / 2);
			x += (a[i] - x) / 2 * 2;
			ans = ans * t;
			if (x != a[i]) {
				ans.a[0][x & 1] = (ans.a[0][x & 1] + ans.a[0][(x & 1) ^ 1]) % mod;
			}
		}
	}
	printf("%lld\n", ans.a[0][(m & 1) ^ 1]);
}

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

/*
g[i][1] = g[i - 1][0] + g[i - 1][1]
g[i][0] = g[i - 1][0] + g[i][1] = 2 * g[i - 1][0] + g[i - 1][1]
*/

标签:AtCoder,typedef,matrix,Beginner,Contest,res,bmod,long,ll
From: https://www.cnblogs.com/zltzlt-blog/p/17444657.html

相关文章

  • AtCoder Beginner Contest 289(E,F)
    AtCoderBeginnerContest289(E,F)E(dijkstra)E这个题的大意就是有两个人,一个人在点\(1\),一个人在点\(n\),现在两个人要同时走(题目给出了点和边,还有每一个点的颜色),但是他们的下一步要到的点需要是颜色不同的,问\(1\)点出发的和\(n\)点出发的同时达到对方的起点的最短路径时哪......
  • AtCoder Beginner Contest 303
    A-SimilarString(abc303a)题目大意给定两个字符串,问这两个字符串是否相似。两个字符串相似,需要每个字母,要么完全相同,要么一个是1一个是l,要么一个是0一个是o解题思路按照题意模拟即可。可以将全部1换成l,全部0换成o,再判断相等。神奇的代码#include<bits/stdc++.h>us......
  • AtCoder Regular Contest 153 D Sum of Sum of Digits
    洛谷传送门AtCoder传送门又浪费一道好题我首先想的是,\(x\)显然最优取某些\(a_i\)往前进位时的值。然后就误以为\(x\)的取值是\(O(n\log_{10}V)\)的了……既然没发现什么性质,那就直接dp吧!设\(f_{d,i}\)为从低到高前\(d\)位,所有\(a_i\)进位之和为\(i\)。然......
  • ROS2-Beginner:CLI tools-1、环境配置
    1、环境配置目标:本教程告诉读者怎样准备ROS2环境背景:ROS2依赖于使用shell环境组合工作空间的概念,“工作区”是一个ROS术语,表示您使用ROS2进行开发的系统上的位置。ROS2的核心工作空间称为底层(underlay)。后续的局部工作空间称为覆盖(overlays)。当使用ROS2进行开发时,通常会同......
  • AtCoder Regular Contest 161
    PrefaceARC战俘闪总出列这场一上来就感觉状态不太对,先是A顺序敲反WA了一发,然后C题看到秒出一个贪心然后也WA了看一眼榜发现D过的比C多,然后跑去把D写了,中间还偷偷挂了两发最后50min回去沉淀C题,结果换了两种写法都还是一样的挂,后面发现想法还是有纰漏总结:彩笔A-MakeM考虑......
  • AtCoder Regular Contest 148 E ≥ K
    洛谷传送门AtCoder传送门是一道不错的计数。考察合法序列的形态,容易发现:不能出现两个\(<\frac{k}{2}\)的数相邻;如果\(x<\frac{k}{2},y\ge\frac{k}{2}\),那么\(|y-\frac{k}{2}|\ge|x-\frac{k}{2}|\)。考虑不直接排列,而是按照一定的顺序插入。考虑按照\(|x......
  • AtCoder Beginner Contest 290(D,E)
    AtCoderBeginnerContest290(D,E)D(思维,数学)D这个题的大意就是我们需要标记\(n\)个位置,他是这样标记的,一开始有一个初始值为\(0\)的\(x\),第一个标记的是\(0\)位置,然后下一步,我们把\(x\)变成\((x+d)modn\),如果这个位置没有被标记,否则把\(x\)变成\((x+1)modn\),这个是没有......
  • AtCoder Regular Contest 161 E Not Dyed by Majority (Cubic Graph)
    洛谷传送门AtCoder传送门给构造题提供了一种新的思路。如果答案占总方案数的比较大,可以考虑随机化。例如本题,考虑随机化,难点变成判断一个方案是否可行。考虑2-SAT,如果一个点是\(\text{B}\),那么对于这个点的边,有一条边的另一个端点是\(\text{W}\),那么其他两个都是\(\text{......
  • AtCoder Beginner Contest 303 题解 A - E
    A-SimilarString题目大意忽略0和o的差别以及1和l的差别比较两个字符串。解题思路可以硬求,直接写个超长的if判断一下。可以对两个字符串进行修改,0都换成o,1都换成l,然后直接比较两个字符串。ACCode硬求#include<iostream>#include<algorithm>#include<cstring>#i......
  • AtCoder Beginner Contest 303 G Bags Game
    洛谷传送门AtCoder传送门经典题,考虑区间dp,\(f_{l,r}\)表示只考虑\([l,r]\)区间,先手得分减后手得分最大值。对于第一种操作直接\(f_{l,r}\gets\max(a_l-f_{l+1,r},a_r-f_{l,r-1})\),第二种操作,考虑枚举\([l,r]\)长为\(r-l+1-B\)的子段,即可转移。第三种操......