数论的第二舞——卡特兰数

当然了,虽然主角是卡特兰数,但是我们该学的数论还是不能落下的,首先先来介绍一个开胃小菜线性筛

1.积性函数: 

2.线性筛 

线性筛的筛选素数的时间复杂度更低,可以达到O(n)的时间复杂度

将每一轮进行筛选的数 n 表示为 i * su[ j ] (即 n = i * su[ j ])。i 为 n 的最大因子,su[ j ] 为 n 的最小因子(最小因子必为质数。如果不为质数,则该数可以分解为两个数的乘积, 与最小因子矛盾)

每个数都只会被筛一次,因此时间复杂度可以达到O(n)

对于一个质数来说,最多会达到他本身,对于一个合数来说,最多会达到他的最小质数

数 n 能被分解成有限个质数相乘,(在这有限个质数当中可能包含了相同的质数,比如300可以分解为2 * 2 * 3 * 5 * 5),将这有限个质数从小到大排列,取出其中最小的质数即为最小因子,再将剩下的数乘起来即为最大因子(比如300的最小因子为2,最大因子为150)

因此就可以完成线性筛的板子

	vis[1]=1;//vis数组用于记录某个数是否是素数,如果是1则不是素数,反之则是
	int cnt=0;//用于统计素数数组的长度
	for(int i=2;i<=n;i++)
	{
		if(!vis[i])//是素数,存进素数数组
		su[++cnt]=i;
		for(int j=1;j<=cnt&&i*su[j]<=n;j++)//进行第i轮的询问
		{
			vis[i*su[j]]=1;//将其标记为合数
			if(i%su[j]==0)//如果会被整除就立马结束
			break;
		}
	}

ps:也是来到了本篇博客的重点,前面两个只是为了后面一道题的铺垫 

3.卡特兰数

我们先列举卡特兰数的一部分序列:1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440

1.通项式

卡特兰数的通项式: 我们用f(n)表示,第n想的卡特兰数

 这时我们还可以通过这个通项式推导出来其另一种表示形式

以及另一种,我不知道怎么推出来的,但是确实是有

 2.递推式

3.卡特兰数的应用:

这里的理解我认为可以将别人总结的多种情形再总结一下,说白了就是封闭式的问题都可以用到卡特兰数,什么叫做封闭式的问题呢?

我的理解就是一种有始有终的问题,就像左右括号的匹配,一个左括号必然要有一个右括号去匹配,这个我也确实不好讲清楚,看个人的理解了

因此可以有以下的应用场景

在开始讲解场景之前,我们首先来考虑一个问题,在数学上如何去确定两个集合中的值是相等的

 假设我们有a,b两个集合,假设我们有一种映射关系f,可以让b集合中的每一个数映射过来都是a集合中的不同的数,那么a>=b,如果我们还有一种隐射关系g,可以让a集合中的每一个数隐射过来都是b集合中的不同的数,那么就可以说a<=b,因此a=b,即两个集合中的元素相同

(1)括号匹配的场景 

给定N个左括号,N个右括号,它们自由组合,必须全部使用,能得到多少个合法的组合

我们能否将这个问题转换一下,假设我们的左括号是是向右上走一步,右括号是向右下走一步,那么最终我们一定会走到(2*n,0)这个点,我们可以来讨论一下不合法的情况,什么时候会存在不合法的情况,那就是我们的前缀出现右括号的数量大于左括号的数量的时候,那种情况放在我们的数学结构中就是,只要y轴上的值小于0,那么就是不合法的

我们想要求合法的序列的种数,我们可以用总的排列数-不合法的排列数=合法的排列数

总的排列数为C(n,2*n)即从2*n个位置里面挑n个作为左括号的位置

我们此时来考虑不合法的数量,因为我们刚才提到一个重要的点,不合法的序列中,一定存在一个前缀使得左括号的数量比右括号的数量少1

比如说: ( ) ) ( ( ) 这种就是不合法的,因为前缀为( ) )很明显右括号的数量大于左括号

假设我们将前缀后面的括号都进行反转,那么上面那个括号序列就变成了( ) ) ) ) (

这样左括号的数量=右括号的数量-2,我们此时可以将这个翻转操作称为映射关系f

因此我们不合法的序列,就变成了n-1个左括号和n+1个右括号,用数学公式表示就是C(n-1,2*n)

因此我们合法的个数就可以直接用组合数学求出来了,即为:

我们可以发现,这不就是卡特兰数的第n项通项式的推导吗?对这就是卡特兰数

(2)入栈出栈问题

给你n个数字判断,总共有多少种出栈序列

这个和上面那个还是一样的,只不过是问法不同的括号匹配问题罢了,我们首先来看一下对于只有1,2两个数都有哪些操作吧

第一种:1进栈 ( '(' )  2进栈 ( '(' ) 1出栈( ')' )  2出栈( ')' )

第二种:1进栈 ( '(' )  1出栈( ')' )  2进栈 ( '(' )  2出栈( ')' )

我们可以将进栈变成左括号,出栈变成右括号,结果还是一样的

所以我习惯性将这种问题,归类到封闭类问题

剩下的情景我就不一一列举了,可以自己想一下

例题

P1044 [NOIP2003 普及组] 栈

也是卡特兰数板题,数据很小,因为没有取模,用递推式最容易写

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

int n, f[30];
int main()
{
    cin>>n;
    f[0] = 1;
	f[1] = 1;
    for(int i=2; i<=n; i++)              
        for(int j=0; j<i; j++) 
            f[i]+=f[j]*f[i-j-1];     
    cout<<f[n];
    return 0;
}

P1641 [SCOI2010] 生成字符串

这个不就是卡特兰数结论的板子吗,但是中间可能会很大,有取模,因此我们可以考虑用线性求逆元,这样O(n)的时间复杂度就可以求出来,然后我们之间敲代码就过了

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int f[2000005];
int inv[2000005];
int mod=20100403;

int fast(int a, int b) 
{
    long long result = 1;
    long long base = a;
    while (b > 0) 
	{
        if (b % 2 == 1) 
		{
            result = (result * base) % mod;
        }
        base = (base * base) % mod;
        b /= 2;
    }
    return result;
}
int cal(int n,int k)
{
	return f[n]*inv[n-k]%mod*inv[k]%mod;
}
signed main()
{
	cin>>n>>m;
	f[0]=1;
	for(int i=1;i<=n+m;i++)
	{
		f[i]=(f[i-1]*i)%mod;
	}
	inv[n+m]=fast(f[n+m],mod-2);
	for(int i=n+m-1;i>=0;i--)
	{
		inv[i]=inv[i+1]*(i+1)%mod;
	}
	cout<<(cal(n+m,n)-cal(n+m,m-1)+mod)%mod;
	return 0;
}

P3200 [HNOI2009] 有趣的数列

我们会发现这题其实也是一个卡特兰数的板子,但是呢?我们的p并不一定是质数,直接把我们逆元的路堵死了,那么我们该如何操作呢?

我后面实在是没想到,于是就去看了大犇们的思路,发现实在是太妙了,我们由唯一分解定理可以知道,任何一个数都可以被拆分成若干个质数的乘积的形式,因此我们可以用线性筛去将所有素数筛选出来,然后用cnt数组去统计每个素数出现的次数,用mp去统计每个数的最小质因数,慢慢分解成质数的形式,最后统计就可以了

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,p;
bool vis[2000005];
int su[2000005];
int cnt[2000005];//统计每个数的指数 
int mp[2000005];
int len;
int fast(int a, int b) 
{
    long long result = 1;
    long long base = a;
    while (b > 0) 
	{
        if (b % 2 == 1) 
		{
            result = (result * base) ;
        }
        base = (base * base) ;
        b /= 2;
    }
    return result;
}
signed main()
{
	cin>>n>>p;
	vis[1]=true;
	len=0;
	for(int i=2;i<=2*n;i++)//先筛选出素数 
	{
		if(!vis[i])
		{
			su[++len]=i;
			mp[i]=i;
		}
		for(int j=1;j<=len&&i*su[j]<=2*n;j++)
		{
			vis[i*su[j]]=true;
			mp[i*su[j]]=su[j];
			if(i%su[j]==0)
			break;
		}
	}
	for(int i=1;i<=n;i++)
	{
		cnt[i]=-1;
	}
	for(int i=n+2;i<=2*n;i++)
	{
		cnt[i]=1;
	}
	for(int i=2*n;i>=2;i--)
	{
		if(vis[i]==1)
		{
			cnt[mp[i]]+=cnt[i];
			cnt[i/mp[i]]+=cnt[i];
		}
	}
	int ans=1;
	for(int i=2;i<=2*n;i++)
	{
		if(vis[i]==0)
		ans=(ans*fast(i,cnt[i]))%p;
	}
	cout<<ans;
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/894155.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Threejs 实现3D 地图(02)创建3d 地图

"d3": "^7.9.0", "three": "^0.169.0", "vue": "^3.5.10" 地图数据来源&#xff1a; DataV.GeoAtlas地理小工具系列 <script setup> import {onMounted, ref} from vue import * as THREE from three im…

Spring Cloud 解决了哪些问题?

大家好&#xff0c;我是锋哥。今天分享关于【Spring Cloud 解决了哪些问题&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; Spring Cloud 解决了哪些问题&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Cloud 是一个为构建分布式…

汽车建模用什么软件最好?汽车建模渲染建议!

在汽车建模和渲染领域&#xff0c;选择合适的软件对于实现精确的设计与高质量的视觉效果至关重要。那么不少的汽车设计师如何选择合适的建模软件与渲染方案呢&#xff0c;一起来简单看看吧&#xff01; 一、汽车建模用软件推荐 1、Alias Autodesk旗下的Alias系列软件是汽车设…

C语言复习第4章 数组

目录 一、一维数组的创建和初始化1.1数组的创建1.2 变长数组1.3 数组的初始化1.4 全局数组默认初始化为01.5 区分两种字符数组1.6 用sizeof计算数组元素个数1.7 如何访问数组元素1.8 一维数组在内存中的存储(连续存储)1.9 访问数组元素的另一种方式:指针变量1.10 数组越界是运行…

【Linux】平台设备驱动

在设备驱动模型中&#xff0c;引入总线的概念可以对驱动代码和设备信息进行分离。但是驱动中总线的概念是软件层面的一种抽象&#xff0c;与我们SOC中物理总线的概念并不严格相等。 物理总线&#xff1a;芯片与各个功能外设之间传送信息的公共通信干线&#xff0c;其中又包括数…

百度AI图片助手 处理本地图片

import random import time import requests import base64 import os import datetime import numpy as np import cv2 from PIL import Image import argparseclass IMGNetProcess(object):"""百度 图片处理"""def __init__(self, file, kind)…

【计算机网络】HTTP报文详解,HTTPS基于HTTP做了哪些改进?(面试经典题)

HTTP协议基本报文格式 在计算机网络中&#xff0c;HTTP&#xff08;超文本传输协议&#xff09;是应用层的一种协议&#xff0c;用于客户端&#xff08;通常是浏览器&#xff09;和服务器之间的通信。HTTP报文分为请求报文和响应报文&#xff0c;以下是它们的基本格式。 1. H…

Java爬虫API:获取商品详情数据的利器

为什么选择Java爬虫API 强大的库支持&#xff1a;Java拥有丰富的网络编程库&#xff0c;如Apache HttpClient、OkHttp等&#xff0c;这些库提供了强大的HTTP请求功能&#xff0c;使得发送请求和处理响应变得简单。高效的数据处理&#xff1a;Java的数据处理能力&#xff0c;结…

如何给手机换ip地址

在当今数字化时代&#xff0c;IP地址作为设备在网络中的唯一标识&#xff0c;扮演着举足轻重的角色。然而&#xff0c;有时出于隐私保护、网络访问需求或其他特定原因&#xff0c;我们可能需要更改手机的IP地址。本文将详细介绍几种实用的方法&#xff0c;帮助您轻松实现手机IP…

计算力学|采用python进行有限元模拟

从abaqus输出的inp文件中读取节点和单元信息 import meshio mesh meshio.read(Job-3.inp) coords mesh.points###coords即为各个节点的坐标 Edof mesh.cells_dict[triangle]#Edof为三角形单元的节点号 1.单元刚度矩阵 def element_stiffness(n1,coords,E,v,t): node1 c…

目标检测——Cascade R-CNN算法解读

论文&#xff1a; Cascade R-CNN: Delving into High Quality Object Detection (2017.12.3) 链接&#xff1a;https://arxiv.org/abs/1712.00726 Cascade R-CNN: High Quality Object Detection and Instance Segmentation (2019.6.24) 链接&#xff1a;https://arxiv.org/abs…

ubuntu22.04下GStreamer源码编译单步调试

前言 本文会通过介绍在linux平台下的GStreamer的源码编译和单步调试example实例。官网介绍直接通过命令行来安装gstreamer可以参考链接&#xff1a;Installing on Linux。 这种方法安装后&#xff0c;基于gstreamer的程序&#xff0c;单步调试的时候并不会进入到gstreamer源码…

LSTM预测:糖尿病的发生情况

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 本期&#xff0c;做个二维结构化数据的分类预测。提到结构化数据&#xff0c;一般的分类算法常用有&#xff1a;逻辑回归&#xff08;二分类&#xff09;、KNN、SVM、决策树、贝叶斯、随机森林、X…

Jenkins配置流水线任务-实践操作(Pipeline-script)

Jenkins配置流水线任务-实践操作(Pipeline-script) 1、新增jenkins 任务&#xff0c;选择流水线 2、参数化 3、流水线配置 pipeline {agent anystages {stage(aoePlugin_mysql) {steps {echo "xxx&#xff0c;数据库:Mysql"echo "${HOST},${USER_NAME}"b…

王爽汇编语言第三版实验1

前言 本系列的文章是对王爽老师的汇编语言中的实验的解答记录&#xff0c;原书一共有17个实验&#xff0c;由于学校的教学流程只做到了第14个实验&#xff0c;因此本文章只会有前十四个实验的解答记录,还有个比较重要的是&#xff0c;文章中会有原书实验中没有的题目&#xff…

C语言 | Leetcode C语言题解之第477题汉明距离总和

题目&#xff1a; 题解&#xff1a; int totalHammingDistance(int* nums, int numsSize) {int ans 0;for (int i 0; i < 30; i) {int c 0;for (int j 0; j < numsSize; j) {c (nums[j] >> i) & 1;}ans c * (numsSize - c);}return ans; }

element plus的el-select分页

摘要&#xff1a; el-select的数据比较多的时候&#xff0c;必须要分页&#xff0c;处理方案有全部数据回来&#xff0c;或者添加搜索功能&#xff0c;但是就有个问题就是编辑的时候回显问题&#xff0c;必须要保证select的数据有对应的id与name匹配回显&#xff01; <el-fo…

如何用pyhton修改1000+图片的名字?

import os oldpath input("请输入文件路径&#xff08;在windows中复制那个图片文件夹的路径就可以):") #注意window系统中的路径用这个‘\分割&#xff0c;但是编程语言中一般都是正斜杠也就是’/‘ #这里写一个代码&#xff0c;将 \ > / path "" fo…

数字图像处理:图像复原应用

数字图像处理&#xff1a;图像复原应用 1.1 什么是图像复原&#xff1f; 图像复原是图像处理中的一个重要领域&#xff0c;旨在从退化&#xff08;例如噪声、模糊等&#xff09;图像中恢复出尽可能接近原始图像的结果。图像复原与图像增强不同&#xff0c;复原更多地依赖于图…

服务器数据恢复—服务器硬盘指示灯亮黄灯,raid崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; 一台浪潮服务器中有一组由6块SAS硬盘组建的RAID。服务器上划分了1个卷&#xff0c;存放Oracle数据库文件。 服务器故障&检测&#xff1a; 服务器上有两个硬盘指示灯亮黄灯&#xff0c;RAID崩溃&#xff0c;服务器不可用。 将故障服务器中所…