首页 > 其他分享 >「AT_diverta2019_2_e」Balanced Piles 题解

「AT_diverta2019_2_e」Balanced Piles 题解

时间:2024-11-13 20:08:01浏览次数:1  
标签:le Piles cm int 题解 元素 Module constexpr Balanced

题意描述

有一个长度为 \(N(2\le N \le 10^6)\) 的数组,一开始所有元素均为 \(0\)。
设 \(M\) 为当前数组中的最大元素,\(m\) 是当前数组中的最小元素,你可以执行若干次以下操作:

  • 选择一个大小为 \(m\) 的元素,把他变为 \(x\),其中 \(M\le x \le M+D\) 且 \(m<x\)。
    求有多少种操作方法使得数组中的所有元素均为 \(H\),对 \(10^9+7\) 取模。
    \(1\le D\le H\le10^6\)。

题解

本题是一道十分 NB 的提前计算题。发现不好记录最小元素的状态,我们转而考虑记录最大元素的。定义 \(dp(x,y)\) 表示当前最大元素为 \(x\),最大元素数量为 \(y\)。尽管我们记录的是最大元素,但它总会在后面变成最小元素,我们只要现在将贡献统计就好了。而最小元素的贡献实际上就是它的排列数(即我们取它的方案数)。转移见下图即可明了:

\(N=4,H=4,D=1\) 时,方案数等价于以下图的 \((0,4)→(4,4)\) 的路径条数:

\(N=4,H=4,D=2\) 时,方案数等价于以下图的 \((0,4)→(4,4)\) 的路径条数:

直接转移即可。时间复杂度 \(\mathcal O(n)\)。

代码

#include <bits/stdc++.h>
using namespace std;

using ci = const int;

using u32 = uint32_t;
using i64 =  int64_t;
using u64 = uint64_t;

const int mod = 1e9 + 7;

constexpr inline int dil(int x) { return x >> 31 ? x + mod : x; }

struct Module {
	using cm = const Module;

	int v;

	constexpr Module() : v() {}
	constexpr Module(int _v) : v(_v) {}

	friend constexpr Module operator+(cm &x, cm &y) {
		return dil(x.v + y.v - mod);
	}
	friend constexpr Module operator-(cm &x, cm &y) {
		return dil(x.v - y.v);
	}
	friend constexpr Module operator*(cm &x, cm &y) {
		return static_cast<u64>(x.v) * static_cast<u64>(y.v) % mod;
	}

	constexpr void operator+=(cm &o) { *this = *this + o; }
	constexpr void operator-=(cm &o) { *this = *this - o; }
	constexpr void operator*=(cm &o) { *this = *this * o; }
};

const int N = 1e6 + 5;

int n, d, h;
Module fct[N], f[N];

int main() {
#ifdef LOCAL
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
#endif

	cin >> n >> h >> d;
	fct[0] = 1;
	for (int i = 1; i <= n; ++i) fct[i] = fct[i - 1] * i;
	f[0] = 1;
	Module sum = 0, tot = 1;
	for (int i = 1; i <= n; ++i) sum += fct[i];
	for (int i = 1; i <= h; ++i) {
		tot += (f[i] = tot) * sum;
		if (i >= d) tot -= f[i - d] * (i == d ? 1 : sum);
	}
	cout << (fct[n] * f[h]).v;

	return 0;
}

参考链接

https://www.cnblogs.com/frank3215/p/diverta2019-2E.html (图片也是这里贺的)

标签:le,Piles,cm,int,题解,元素,Module,constexpr,Balanced
From: https://www.cnblogs.com/cqbzljh/p/18544701

相关文章

  • [ARC105C] Camels and Bridge 题解
    [ARC105C]CamelsandBridge题解https://www.luogu.com.cn/problem/AT_arc105_c记:这是24年夏天在北京梦熊写的(模拟赛撞原),希望这年夏天fowever。sol首先\(n\)很小,所以可以去暴力枚举顺序,也就是全排列。\(W_s\)表示排列为\(s\)时的间距。又令\(f_i\)为前\(i\)只......
  • [题解]P3119 [USACO15JAN] Grass Cownoisseur G
    P3119[USACO15JAN]GrassCownoisseurG显然我们可以先跑强连通分量,由\(x\)个点缩成的新点\(u\)权值为\(v[u]=x\)。下文中的节点\(1\)均表示缩点后节点\(1\)所在的节点。我们在缩点后的DAG上跑拓扑排序,预处理出\(fa[i]\)和\(fb[i]\),分别表示“\(1\)到\(i\)路径的点权和”,“\(i......
  • 洛谷P11228的C++题解
    题目分析题目题目让我们算出机器人走步后经过了多少个不重复的点这道题不是搜索!直接按照题意模拟就行了。遇到墙就向右转,不是就直行。特别注意:向右转也是一步!一个格子最多算一遍!我们可以用一个标记数组 st,走过的点就打上标记。判断走道的点有没有打上标记,有就不......
  • P2779 [AHOI2016初中组] 黑白序列题解
    题意:小可可准备了一个未完成的黑白序列,用B和W表示黑色和白色,用?表示尚未确定。他希望知道一共有多少种不同的方法,在决定了每一个?位置的颜色后可以得到一个小雪喜欢的黑白序列。其中,小雪喜欢的黑白序列指的是对于任何正整数\(n\),由连续\(n\)个黑接上连续\(n\)个白......
  • 题解:CF2025E Card Game
    在这貌似和大部分做法不太一样(?)权当卡特兰数的复习题吧。不会卡特兰数的可以先看文末。如果没有花色\(1\)这道题就很简单了,对于每个别的花色都有\(C(m)\)种分配方案。\(C(n)\)表示卡特兰数的第\(n\)项,答案就是乘起来。发现除了花色\(1\)每种花色的牌都是独立的。这......
  • P6628 [省选联考 2020 B 卷] 丁香之路 题解
    P6628[省选联考2020B卷]丁香之路题解首先考虑题目中路径权值的含义:\(i,j\)两点之间的最短路就是\(|i-j|\)直接连边。题目要求从\(s\)遍历到每个点,到终点每个\(x\)的最短时间。于是我们不妨枚举每个\(x\),考虑在\(O(n)\)至\(O(n\logn)\)的时间复杂度里解决问题......
  • 《统计每个月兔子的总数》 递归、记忆化数组、动态规划题解
    目录题目描述输入描述输出描述解析完整代码描述有一对兔子,从出生后第3个月起每个月都生一对兔子,一对小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第n个月(n<=50)的兔子总数为多少对?输入描述输入1个整数n,表示第几个月输出描述第n个月兔子的总数量有多少?......
  • P10833 [COTS 2023] 下 Niz题解
    题意:给定长度为\(N\)的序列\(a\),求满足以下条件的\((l,r)\)对数:\(1\lel\ler\leN\);\(a_l,a_{l+1},\cdots,a_{r-1},a_r\)是\(1\simr-l+1\)的排列。\(1\leN\le10^6\);\(1\lea_i\leN\)。思路首先,“排列”本身这个性质是很强的。因为排列本身需要从1开......
  • AT_agc011_d [AGC011D] Half Reflector 题解
    用\(1\)表示A,\(0\)表示B,观察进行一次操作后字符串会发生什么变化。首先当第一个数为\(1\)时,只会将第一个数变为\(0\)。对于剩下的情况,手玩一下可以发现会将第一个数移到末尾,然后将所有数异或\(1\)。先考虑暴力怎么做,可以记一个指针\(i\)和当前应该给全体数异或的值\(......
  • P10856 【MX-X2-T5】「Cfz Round 4」Xor-Forces题解
    题意:给定一个长度为\(n=2^k\)的数组\(a\),下标从\(0\)开始,维护\(m\)次操作:给定\(x\),设数列\(a'\)满足\(a'_i=a_{i\oplusx}\),将\(a\)修改为\(a'\)。其中\(\oplus\)表示按位异或运算。给定\(l,r\),查询\(a\)的下标在\(l,r\)之间的子数组有多少颜色段。不保......