2018/4/12训练日记 随机增量法/斯特林公式/矩阵快速幂

这两天看了一些博客,挑出一些之前没看过的和比较重点的写一下(比如说矩阵快速幂)

随机增量法

用来解决n个点最小圆覆盖的题

随机增量法的定义和证明不在这里解释(我也没看明白)

过程大体是以下流程:

1.将数组重新打乱

2.假设前i个点最小圆覆盖为Ci,检查第i+1个点,若在圆上,则C(i+1)=Ci,继续判

不在:令C(i+1)为第一个点和第i+1个点连线中点,半径为连线长度一半

3.重新检查前i个点是否在圆C(i+1)上。不在的话 令C(i+1)圆心为三角形(i,j,k)外心,并扩增圆C(i+1)半径

例题参考一下 bzoj1336,明天抽时间写一下题解


斯特林公式

斯特林公式(Stirling's approximation)是一条用来取n的阶乘近似值的数学公式。一般来说,当n很大的时候,n阶乘的计算量十分大,所以斯特林公式十分好用,而且,即使在n很小的时候,斯特林公式的取值已经十分准确。

  1. n! = ((2*pi*n)^(1/2))*((n/e)^n); 前提是n>3  
  2. //由此可以导出lg(n!) = (lg(2*pi)+lg(n))/2 + n*(lg(n)-lg(e));  

主要是用来求n!的位数

将上式取整形再加一就是位数

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
const double e = 2.71828182845;
const double pi = 3.1415926;
int main(void) {
int t, i, f, v;
double a, s;
const double log10_e = log10(e);
const double log10_2_pi = log10(2.0*pi)/2.0;
while (scanf("%d", &t) != EOF && t) {
for (i = 0; i < t; ++i) {
scanf("%d\n", &v);
if (1 == v) {printf("1\n"); continue;}
a = v;
s = log10_2_pi + (a+0.5)*log10(a) - a * log10_e;
f = ceil(s);
printf("%d\n", f); } }
return 0; }

很经典的求法,但之前不了解


矩阵快速幂

其实说矩阵快速幂之前是写过一两篇博客了,今天又看到了几篇博客感觉比较重要,就再写一写回想一下吧


找了一个简单计算矩阵的模板

https://blog.csdn.net/NYIST_TC_LYQ/article/details/52981353

例题的话 比如说

POJ 3070 题目,让求斐波那契数列,其n更是高达10亿

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值