首页 > 其他分享 >P7213 [JOISC2020] 最古の遺跡 3

P7213 [JOISC2020] 最古の遺跡 3

时间:2025-01-10 19:57:36浏览次数:1  
标签:ifac 最古 int ll JOISC2020 ans P7213 include MOD

考虑另一种刻画过程的方式:设 \(a_i\) 为原序列,\(b_i\) 为最终序列,则有:

  • 从后往前扫描,\(b_i\) 会持续降低到 \([i+1, n]\) 中未出现 \(b_i\)。

考虑 dp,设 \(f(i, j)\) 表示考虑了 \([i, n]\),当前在 \(b\) 中 \(1 \sim j\) 都出现过的方案数。这里要区分相等的两个数,且只填了 \([1, j]\) 中的数,\([j+1,n]\) 中的数还没分配位置。

若 \(b_i\) 最终降到 \(0\):

  • \(i\) 处可以填 \([1, j]\),假设 \([i+1,n]\) 中一共有 \(c_0\) 个 \(0\),则系数为 \(j - c_0\)。

若 \(b_i\) 最终不为 \(0\):

  • 若 \(b_i> j + 1\),则现在先不分配 \(a_i\),系数为 \(1\)。
  • 若 \(b_i = j + 1\),枚举此时 \(1 \sim j + k\) 都出现过,则有:
    1. 要在 \([j+1,n]\) 中的非 \(0\) 位置里选出 \(k-1\) 个位置,系数为 \(\dbinom{n-i-c_0}{k-1}\)。
    2. \(a_i\) 可以填 \([j+1, j + k]\),且 \(j+1\) 有两种选择,系数为 \(k+1\)
    3. 后面 \(k - 1\) 个位置可以填 \([j+2,j+k]\),且最终要形成 \(j+2 \sim j+k\) 的排列,假设系数为 \(g(k-1)\)。

设有 \(g(n)\) 表示 \(n\) 个位置,\(a_i \in [1, n]\),且 \(b_i\) 构成 \(1 \sim n\) 的排列的方案数。

转移考虑枚举 \(b_n = i\),则转化为 \([1, i - 1]\) 和 \([i+1, n]\) 的子问题,有

\[g(n) = \sum_{i=1}^{n} \binom{n - 1}{i - 1}(n - i + 1)g(i - 1)g(n- i) \]

总时间复杂度 \(\mathrm{O}(n ^ 3)\)。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
using ll = long long;
const int N = 610;
const int M = 1210;
const int MOD = 1e9 + 7;
int n, m, occur[M];
ll fac[M], ifac[M], f[M][N], g[N];
ll Pow(ll a, int p = MOD - 2) {
	ll ans = 1;
	for(; p; p >>= 1, a = a * a % MOD)
		if(p & 1) ans = ans * a % MOD;
	return ans;
}
ll C(int n, int m) {
	if(n < 0 || m < 0 || n < m) return 0;
	return fac[n] * ifac[m] % MOD * ifac[n - m] % MOD;
}
int main() {
	//freopen("data.in", "r", stdin);
	//freopen("code.out", "w", stdout);
	cin.tie(0)->sync_with_stdio(0);
	cin >> n, m = n * 2;
	for(int i = 1, x; i <= n; ++i)
		cin >> x, occur[x] = 1;
	fac[0] = 1;
	for(int i = 1; i <= m; ++i)
		fac[i] = fac[i - 1] * i % MOD;
	ifac[m] = Pow(fac[m]);
	for(int i = m - 1; i >= 0; --i)
		ifac[i] = ifac[i + 1] * (i + 1) % MOD;
	g[0] = 1;
	for(int x = 1; x <= n; ++x)
		for(int i = 1; i <= x; ++i)
			g[x] = (g[x] + C(x - 1, i - 1) * (x - i + 2) % MOD * g[i - 1] % MOD * g[x - i]) % MOD;
	f[m + 1][0] = 1;
	int c0 = 0, c1 = 0;
	for(int i = m; i >= 1; --i) {
		for(int j = 0; j <= n; ++j) if(f[i + 1][j]) {
			if(occur[i]) {
				f[i][j] = (f[i][j] + f[i + 1][j]) % MOD;	
				for(int k = 1; k <= n - j; ++k)
					f[i][j + k] = (f[i][j + k] + C(c1 - j, k - 1) * (k + 1) % MOD * f[i + 1][j] % MOD * g[k - 1]) % MOD;				
			}
			else {
				f[i][j] = (f[i][j] + f[i + 1][j] * (j - c0)) % MOD;	
			}
		}
		c0 += occur[i] == 0, c1 += occur[i] == 1;
	}
	printf("%lld\n", f[1][n] * Pow(Pow(2, n)) % MOD);
	return 0;
}

标签:ifac,最古,int,ll,JOISC2020,ans,P7213,include,MOD
From: https://www.cnblogs.com/Aria-Math/p/18664569

相关文章

  • P7215 JOISC2020 首都
    P7215JOISC2020首都点分治好题。思路求出当前分治中心,把当前分治中心作为首都,暴力跑需要合并多少个城市,不能越过上一层分治中心。如果越过了上一个分治中心,把上一个分治中心作为首都也可以起到相同的效果,就没有必要再跑一次了。时间复杂度\(O(n\logn)\)。CODE#include<......
  • JOISC2020 Day 4 A 首都 题解
    JOISC2020Day4A首都JOIAtCoderLuogu考虑一条链的情形。如图,将每个城市视为一条线段,容易发现交错(有交但不包含)的若干线段必须全部合并才能符合条件。但如果这么写会出错,原因是线段有包含关系,外层线段需要统计内层线段的答案,但内层线段不需要统计外层线段的答案。如果设内......
  • P7215 [JOISC2020] 首都]
    P7215[JOISC2020]首都考虑对于颜色\(c_i\),若在此颜色集合内所有节点之间的路径上出现了其他颜色(如\(c_j\)),那我们则不得不将这两种颜色合并在一起,操作数加一。即对于颜色\(c_i\),若设其为首都,其答案(操作数)为所有颜色为\(c_i\)的节点之间的路径上的颜色种类......
  • P7219 [JOISC2020] 星座 3 题解
    会发现题目的坐标其实是平面直角坐标系。我们按\(y\)坐标从小到大考虑所有的星星,假设当前考虑到了星星\(i\)。我们先计算出之前所有能够影响到\(i\)的星星的代价和为\(cost\)(可以用树状数组维护)。然后分类讨论。若\(c_i\lecost\),那么肯定直接将\(i\)直接涂黑,因为它更......
  • P7219 [JOISC2020] 星座 3【笛卡尔树+整体dp】
    P7219[JOISC2020]星座3笛卡尔树+整体dp(线段树合并维护dp)考虑转化题意,不存在矩形为星座,即对于每个极大矩形中都只有一颗星星。而观察题目的方格,对于两个位置是否能够成为一个矩形,只和两个位置的区间最大值(小白船的位置)有关①。图中的红蓝矩形即为两个极大矩形。将删除星......
  • JOISC2020
    [JOISC2020]最古の遺跡3好难的题。首先考虑给出\(h\)怎么求\(A\),设\(h'_i\)为\(i\)位置剩下的高度,没了就\(=0\)。方便起见,我们把原序列翻转一下,那么题目的操作就是,每种高度的最靠左的位置不变。我们从左到右依次求解,先令\(h'_i=h_i\),若\(h'_i\)在\(j<i\)的\(......
  • [JOISC2020] 扫除
    现在Bitaro准备用扫帚打扫房间。我们认为扫帚是放置在房间里的一条线段,并且将这条线段的长度称为扫帚的宽度。由于Bitaro很有条理,所以他只会用以下的两种方式打扫房间:Bitaro将扫帚平行于\(y\)轴放置,一端位于原点。然后他会垂直向右移动扫帚,直到不能移动为止。如果扫帚的......
  • [JOISC2020] 最古の遺跡 3
    [JOISC2020]最古の遺跡3题目背景JOI教授是一名研究IOI王国的历史学家。题目描述他发现了一行古代石柱的废墟及一份古代文献。古代文献上的记载如下:刚建造完成的时候,有\(2\timesN\)个石柱,对于\(1\lek\leN\)均有两个石柱高度为\(k\),同时记第\(i\)个石柱的高度......
  • JOISC2020题解
    \(\text{ByDaiRuiChen007}\)ContestLinkA.Building4ProblemLink题目大意给\(2n\)个数对\((a_i,b_i)\),构造一个非降序列\(c_i\)满足\(\forall1\lei\len,c_i\in\{a_i,b_i\}\),且\(c_i=a_i\)的位置恰好有\(n\)个。数据范围:\(n\le5\times10^5\)。思路......
  • P6891 [JOISC2020] ビルの飾り付け 4
    P6891[JOISC2020]ビルの飾り付け4题目传送门Problem给定长度为\(2n\)(\(1\len\le5\times10^5\))的序列\(A\),\(B\)。要求构造一个单调不降的序列\(C\)。每个\(C_i\)从\(A_i\)和\(B_i\)中选取,且\(A\),\(B\)中都恰好选取\(n\)个。Solution最直接的想法显然是dp......