2021牛客国庆集训派对day6 C Generation I

博客讨论了一个关于数学组合和逆元的编程问题。给定一个三角形矩阵,每行代表一个集合,需要填充特定数字以形成不同集合。题目解析了关键性质和解决方案,涉及子集概念、数字顺序的影响以及乘法逆元的使用。通过扩展欧几里得算法计算逆元,并给出C++代码实现,用于计算可能的集合数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

Oak is given N empty and non-repeatable sets which are numbered from 1 to N.

Now Oak is going to do N operations. In the i-th operation, he will insert an integer x between 1 and M to every set indexed between i and N.

Oak wonders how many different results he can make after the N operations. Two results are different if and only if there exists a set in one result different from the set with the same index in another result.

Please help Oak calculate the answer. As the answer can be extremely large, output it modulo 998244353.

本文参考了文章牛客网暑期ACM多校训练营(第六场) C (简单排列组合+逆元)_Jiandong-优快云博客

题意解析:

给定n行,每行具有n个数字,我们需要对这个三角形进行填写数字的操作,对于每一列,我们都需要填写相同的数字,但是这些数字是从1--m,每行作为一个集合,请问我们可以构造出多少个集合的数量

首先我们通过题目可以得出以下几个性质:

1.对于任意第i(i <= n - 1)行,第i行构成的集合必定是第(i + 1)行的子集

2.在最后一行填入数字相同的情况下,填入数字的顺序会影响集合的构成

比如以下两个数字三角形

1                                       1

1    2                                 1   3

1    2    3                           1   3   2

他们所构成的集合是不一样的

因此我们可以知道,最后一行的数字的顺序会影响相应集合的构成

我们对最后一行需要取的数字个数考虑

假设我们需要取K个,然后对这K个相对出现位置进行排序

排序完之后我们需要考虑这些数字第一次出现的位置,则是C(K - 1,N - 1);

对应的式子如下所示

C\binom{k}{m} *A\binom{k}{k} * C\binom{k - 1}{n - 1}

化简之后得到

A\binom{k}{m} * C\binom{k - 1}{n - 1}

然后对于带有除数的式子,进行乘法逆元的操作,接下来就可以解决了

乘法逆元:替代mod 中除以A,用乘以A的逆元来替代

一个数A的逆元(p为质数)数的(p - 2)次方

求逆元更普遍的方式是采用扩展欧几里得的方式

void exgcd(ll a,ll b,ll& d,ll& x,ll& y)
{
    if(!b) { d = a; x = 1; y = 0; }
    else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); }
}

ll inv(ll a, ll p)
{
    ll d, x, y;
    exgcd(a, p, d, x, y);
    return d == 1 ? (x+p)%p : -1;
}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
const ll mod = 998244353;
ll n,m;
int T;
ll inv[maxn];
ll quickpow(ll a,ll b)
{
	if(b == 0) return 1;
	if(b & 1) return (quickpow(a,b - 1) % mod) * (a % mod) % mod;
	else
	{
		ll tmp = quickpow(a,b >> 1) % mod;
		return (tmp % mod) * (tmp % mod) % mod;
	}
}
void pre()
{
	for(int i = 1;i <= maxn - 8;++i)
	{
		inv[i] = (quickpow(i,mod - 2) + mod) % mod;
	}
}
int main()
{
	scanf("%d",&T);
	pre();
	for(int u = 1;u <= T;++u)
	{
		ll ans = 0;
		scanf("%lld %lld",&n,&m);
		ll end = min(n,m);
		n %= mod;
		m %= mod;
		ll mul = m;
		ll sum = 1;
        ans = m;
       // cout << inv[1] <<"\n";
		for(ll i = 1;i < end;++i)
		{
			mul = mul % mod * ((m - i) % mod) % mod;
			sum = sum % mod * (inv[i]) % mod * ((n - i) % mod) % mod;
			ans += (mul % mod) * (sum % mod) % mod;
		}
		ans = (ans + mod) % mod;
		printf("Case #%d: %lld\n",u,ans);
	}
	return 0;
}

### 四旋翼无人机Simulink轨迹仿真 #### 建立四旋翼无人机的动力学模型 对于四旋翼无人机的建模,需要考虑到多个方面的影响因素,包括但不限于空气阻力、螺旋桨间的相互作用以及气流干扰等因素[^1]。这些复杂的动力学特性可以通过构建六自由度(6-DOF)的动力学模型来实现更为精确的描述[^4]。 #### 设计控制器并进行仿真验证 采用PD串级控制策略能够有效地提高四旋翼飞行器沿预定路径飞行的能力,在Simulink环境下完成该类系统的搭建有助于加深对四轴飞行器工作原理和技术细节的理解[^2]。具体来说,通过调整比例(P)和微分(D)参数可以使飞行器更好地跟随给定的目标位置变化而移动。 #### 创建逼真环境以测试性能表现 为了让仿真的效果更加贴近实际情况,还可以利用MATLAB/Simulink平台提供的功能进一步增强实验的真实性。例如,借助于`Simulink 3D Animation`工具箱可以轻松地向场景内引入各种类型的静态或动态物体作为潜在碰撞对象;同时也能方便地观察到整个过程中的视觉反馈情况[^3]。 下面给出一段简单的Matlab代码用于初始化一个基本框架: ```matlab % 初始化 simulink 模型 model = 'quadrotor_trajectory_simulation'; open_system(model); % 设置初始条件 set_param([model '/Initial State'], ... 'Position', '[0; 0; 0]', ... % 初始坐标 (x,y,z) 'Velocity', '[0; 0; 0]', ... % 初始速度 vx,vy,vz 'Attitude', '[0; 0; 0]' % 初始姿态角 roll,pitch,yaw ); ``` 此段脚本展示了如何打开预先准备好的simulink文件,并设定一些必要的物理属性值以便后续操作。当然实际应用时还需要根据具体的任务需求完善更多细节部分,比如定义期望经过的关键点序列或者指定特定的时间间隔等信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值