MEX Sequences (state machine DP)

Posted by Stressed on Thu, 03 Feb 2022 07:04:39 +0100

MEX Sequences

[Link](Problem - D - Codeforces)

meaning of the title

Give you a sequence x n x_n xn, how many subsequences do you satisfy ∣ x i − M E X ( x 1 , x 2 , . . . , x i ) ( lower mark by son order column of lower mark ) ∣ ≤ 1 |x_ I-mex (x_1, x_2,..., x_i) (subscript is the subscript of subsequence) | \ le1 ∣ xi − MEX(x1, x2,..., xi) (subscript is the subscript of subsequence) ∣ ≤ 1

thinking

First, consider how to divide the scheme. Let's consider a certain value x x Divide the scheme by the end of x.

Traversal from front to back, for a certain number x x For the sequence at the end of x, he can receive the previous sequence and must be satisfied after the sequence is arranged

  1. from 0 0 0 to x − 1 x-1 x − 1 continuous or 0 0 0 to x x x continuous and then add x x x this time m e x = x + 1 mex=x+1 mex=x+1 meets the conditions
  2. 0 , . . . , x − 2 , x 0,...,x-2,x 0 X − 2,x, i.e. no longer exists x − 1 x-1 x − 1 at this time m e x = x − 1 mex=x-1 mex=x − 1 meets the conditions

set up f [ x ] : with x junction tail of order column of Tribute offer f[x]: contribution of sequences ending with X f[x]: the contribution of the sequence ending with X. considering the contribution, for the first one, we can directly f [ x ] + = f [ x − 1 ] + f [ x ] f[x]+=f[x-1]+f[x] f[x]+=f[x − 1]+f[x], for the second contribution, it is found that it is also in our state f [ x ] f[x] f[x], this is definitely wrong. If the design state is like this, for f [ x + 1 ] f[x+1] f[x+1] will exist when it is transferred 0 , . . , x − 2 , x , x + 1 0,..,x-2,x,x+1 0 Legal sequences such as X − 2,x,x+1 will also contribute, so add one dimension.

Status indication: f [ x ] [ 0 ] : with x junction tail of strip piece 1 of order column of Tribute offer , f [ x ] [ 1 ] : with x junction tail of strip piece 2 of order column of Tribute offer f[x][0]: contribution of the sequence of condition 1 ending with X, f[x][1]: contribution of the sequence of condition 2 ending with X f[x][0]: contribution of the sequence of condition 1 ending with X, f[x][1]: contribution of the sequence of condition 2 ending with X

State transition:

Condition 1: f [ x ] [ 0 ] + = f [ x − 1 ] [ 0 ] + f [ x ] [ 0 ] f[x][0]+=f[x-1][0]+f[x][0] f[x][0]+=f[x−1][0]+f[x][0]

Condition 2: f [ x ] [ 1 ] + = f [ x ] [ 1 ] f[x][1] += f[x][1] f[x][1]+=f[x][1], f [ x ] [ 1 ] + = f [ x − 2 ] [ 0 ] ∣ x > 1 f[x][1]+=f[x-2][0]|x>1 f[x][1]+=f[x−2][0]∣x>1

Also maintain the transferred f [ x + 2 ] [ 1 ] + = f [ x + 2 ] [ 1 ] f[x+2][1]+=f[x+2][1] f[x+2][1]+=f[x+2][1]

Because we value d p dp dp is relatively out of order, so it is correct to transfer all the states that can be affected by the current added value to.

In order to place the data that will be read in out of bounds x x x-pass one plus one is equivalent to moving the interval right, and the result remains unchanged.

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <bitset>
#include <unordered_map>
#include <cmath> 
#include <stack>
#include <iomanip>
#include <deque> 
#include <sstream>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 5e5 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod =  998244353;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
#define tpyeinput int
inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;}
inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();}
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {
	e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int n, m, k;
int a[N];
LL f[N][2];
//0123
//0111333
int main() {
	ios::sync_with_stdio(false), cin.tie(0);
	int T;
	cin >> T;
	while (T -- ) {
		cin >> n;
		for (int i = 1; i <= n + 2; i ++) f[i][0] = f[i][1] = 0;
		f[0][0] = 1;
		for (int i = 1; i <= n; i ++) {
			int x; cin >> x, x ++;
			f[x][0] += f[x][0] + f[x - 1][0]; // X ends with mex as x-1 or x+1
			f[x][1] += f[x][1];
			f[x + 2][1] += f[x + 2][1];
			if (x > 1) f[x][1] += f[x - 2][0];
			
			f[x][0] %= mod;
			f[x][1] %= mod;
			f[x + 2][1] %= mod;
		}
		
		LL res = 0;
		for (int i = 1; i <= n + 2; i ++)
			res = (res + f[i][0] + f[i][1]) % mod;
		
		cout << res << endl;
	}
	return 0;
}

Topics: Algorithm Dynamic Programming greedy algorithm