[03.28] Number of two analog GDOI2020 number (TWO) (count dynamic programming):

First consider how to determine the legality of an inquiry set.

Consider a query \ ([l, r] \ ) , can \ ([1, l-1 ] ∪ [r + 1, n] \) and \ ([l, r] \ ) to keep separate.

Now a block is defined as a maximum point are not separated collection area.

When all the block size is 1, the program is legitimate.

nature:

1. The block is composed of a number of consecutive segments, such as the following:

1112233111411

Color block 1 consists of three sections of consecutive segments.

CROSS situation does not occur between the blocks 2:

For example, the following:

11122211122211

Also he said that the relationship between the two blocks, only fully contained and mutually exclusive two kinds.

Set \ (f [i] \) represents the length of \ (I \) , the size of each block is a number of programs.

The total consideration minus illegal.

The number of illegal schemes: first enumerate a non-legal division of the state block, then consider seeking becomes so how many kinds of programs.

For an illegal block divided state, we can only whichever is the outermost point of the leftmost and rightmost point block to count it.

Outermost block: not contain any block other blocks.

For example, \ (112 131 145 657 \) , left: \ (1 ????? 14557 \?)

For \ (?? ...? \) In the middle of the side, it can easily take.

For the retained block \ (5, 7 \) , to distinguish between them, the program number is \ (F [number of blocks outermost] \)

Transfer:

Consider enumeration size \ (> 1 \) the number of the outermost block, then inserted to enumerate size \ (> 1 \) an outermost layer of the intermediate block \ (? \) Number y, the size \ (= 1 \) is the number of blocks outermost \ (z = i-2x- y \)

A pretreatment \ (g [i] [j ] \) represents the \ (J \) number is inserted into \ (I \) coefficient and the product of blocks, \ (G [I] [J] = \ sum_ {k = 1} ^ jg [ i-1] [jk] * 2 ^ {k (k + 1) / 2} \)

那么\(f[i]=2^{i(i+1)/2}-\sum_x\sum_{y,z=i-2x-y} g[x][y]*f[x+z]*{(x+z)!\over x!z!}\)

Wherein \ ({(x + z) ! \ Over x! Z!} \) Is the number of the outermost block permutation scheme.

Code:


#include<bits/stdc++.h> 
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

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

const int N = 305;

ll a2[N * N + N];
ll f[N], h[N][N];
ll fac[N], nf[N];

int main() {
	freopen("two.in", "r", stdin);
	freopen("two.out", "w", stdout);
	scanf("%d %d", &n, &mo);
	a2[0] = 1; fo(i, 1, (n + 1) * n) a2[i] = a2[i - 1] * 2 % mo;
	f[1] = 1;
	fac[0] = 1; fo(i, 1, n) fac[i] = fac[i - 1] * i % mo;
	fd(i, n, 0) nf[i] = ksm(fac[i], mo - 2);
	h[0][0] = 1;
	fo(i, 0, n - 1)	{
		fo(j, 0, n) fo(k, 0, n - j)
			h[i + 1][j + k] = (h[i + 1][j + k] + h[i][j] * a2[k * (k + 1) / 2]) % mo;
	}
	f[1] = 2;
	fo(i, 2, n) {
		f[i] = a2[i * (i + 1) / 2];
		fo(x, 1, i / 2) fo(y, 0, i - 2 * x) {
			int z = i - 2 * x - y;
			ll v = h[x][y] * f[i - y - x] % mo;
			v = v * fac[z + x] % mo * nf[z] % mo * nf[x] % mo;
			f[i] = (f[i] - v) % mo;
		}
	}
	pp("%lld\n", (f[n] % mo + mo) % mo);
}

Guess you like

Origin www.cnblogs.com/coldchair/p/12589976.html