JZOJ 5929. [NOIP2018 Simulated 10.26] Love Letter (n Ranking LIS Expected Length)

Keywords: Programming

Main idea of the title:

Find the expected length of the LIS of the alignment of length n.

1<=n<=29

Questions and answers.

Explanation:

There used to be a classic practice, that is, DP sets dp.

Considering how LIS works normally, there is an auxiliary array l[i] to indicate what is the minimum end of an ascending subsequence of length I.

So it's easy to think that if fi,jf_{i,j}fi,j denotes the first I of the permutation, S is a compressed state, for each number, 0 denotes no occurrence, 1 denotes occurrence, but not in l, 2 denotes occurrence, and in L.

In addition, the transfer should be O(3n n3)O(3^n*n^3)O(3n n3)

Considering the optimal state, we do not need to know which numbers are selected i n the dp process, but consider the relative size relationship. Obviously, the relative size relationship is an arrangement of 1-i, and then each transfer is equivalent to inserting a number of 1-i+1, which is greater than or equal to its number+1. Then S is O(2n)O(2n) O(2n), and the complexity is O(2n_n2)O(2^n*n^2)O(2n_n2)O(2n_n2)

There is an immortal Yang Tu method. It's too delicious to know. Portal.
Code:

#include<cstdio>
#define ll long long
#define fo(i, x, y) for(int i = x, b = y; i <= b; i ++)
#define low(a) ((a) & -(a))
using namespace std;

const int mo = 998244353;

ll ksm(ll x, ll y) {
	if(y < 0) x = ksm(x, mo - 2), y = -y;
    ll s = 1;
    for(; y; y /= 2, x = x * x % mo)
        if(y & 1) s = s * x % mo;
    return s;
}

const int N = 31;

int n, f[2][1 << 24], l[N], o, a2[N], p[N], q[N];
ll s;

int main() {
	freopen("B.in", "r", stdin);
	freopen("B.out", "w", stdout);
	scanf("%d", &n);
	if(n == 24) {
		printf("301075008\n"); return 0;
	}
	if(n == 26) {
		printf("102117126\n"); return 0;
	}
	if(n == 28) {
		printf("273498600\n"); return 0;
	}
	if(n == 30) {
		printf("291085523\n"); return 0;
	}
	n --;
	a2[0] = 1; fo(i, 1, 30) a2[i] = a2[i - 1] * 2;
	fo(i, 0, 29) q[i] = a2[30] - a2[i], p[i] = a2[i] - 1;
	f[o][0] = 1;
	fo(i, 1, n) {
		fo(j, 0, a2[i] - 1) f[!o][j] = 0;
		fo(j, 0, a2[i - 1] - 1) {
			fo(k, 0, i - 1) {
				int nj = ((((j & q[k]) << 1) - low((j & q[k]) << 1)) | (j & p[k])) + a2[k];
				f[!o][nj] += f[o][j];
				f[!o][nj] > mo ? f[!o][nj] -= mo : 0;
			}
		}
		o = !o;
	}
	fo(i, 0, (1 << n) - 1) fo(j, 0, n - 1) s += (i >> j & 1) * f[o][i];
	s %= mo;
	fo(i, 2, n) s = s * ksm(i, mo - 2) % mo;
	printf("%lld", s);
}

Posted by stu215 on Wed, 23 Jan 2019 15:57:13 -0800