数学专题
坑
- 多组处理的时候,对于使用全局状态数组需要使用memset初始化
思路总结
-
二分法有多种写法
-
使用筛法进行打表预处理,进行优化
-
使用long long或者unsigned long long防止溢出
-
关于double的几个细节
//double很大的时候,+-0.5会没有影响 double d = 1e15; printf("%lf %lf %lf", d, d+0.5, d-0.5); //输入输出会有影响 scanf("%lf", &d); printf("%f", d);//标准是f,有的允许使用lf
-
几个数学常用公式
-
sin,cos,tan:使用时候需要注意参数是弧度不是角度
-
asin,acos,atan返回值为弧度
-
PI=acos(-1)
-
abs,fabs分别计算整型,浮点数的绝对值
-
pow返回值为double,并且求幂效率低,还可能溢出(可以使用快速幂改进)
-
距离
- 欧式距离sqrt((x1-x2)(x1-x2) + (y1-y2)(y1-y2))
- 曼哈顿距离:|x1-x2|+|y1-y2|
-
sqrt优化:计算一个数的因子,可以只枚举1-sqrt(n)【可以证明如果1-sqrt(n)都没有,那么sqrt(n)之后也没有】
-
同余定理
- (a±b)%mod = (a%mod±b%mod)%mod
- (a*b)%mod = (a%mod*b%mod)%mod
-
容斥原理
- |A∪B| = |A|+|B| - |A∩B|
- |A∪B∪C| = |A|+|B|+|C| - |A∩B| - |B∩C| - |C∩A| + |A∩B∩C|
-
GCD和LCM
-
GCD计算最大公约数,使用碾转相除法
int gcd(int a, int b){ return b == 0 ? a : gcd(b, a % b); } int gcd(int a, int b){ return __gcd(a, b);//内置 }
-
LCM计算最小公倍数
int LCM(int a, int b){ return a / gcd(a, b) * b;//有个细节,要先除后乘,避免可能的溢出 }
-
-
作业
- 1348
- 第一个忘记多组处理初始化
- 思路不对,计算水坑应该找左右两端,我只考虑了使用单调栈计算每个水柱右边最高的最近的柱子,这样导致2 0 1的数据会算不出来,因为2对应的柱子右边没有比它高的,没法计算水坑了。正确思路是从0对应的柱子,找左右,在计算
- 1034
- 这题使用单调队列来保证子序列字典序最小,通过设置进入单调队列的元素的处理来设置子序列长度
题号
-
PIPIOJ 1154 球的半径和体积(基本公式运用)
-
PIPIOJ 1103 PIPI的数学题I (同余定理)
-
PIPIOJ 1352 多个数最小公倍数(公约数与公倍数)
-
PIPIOJ 1341 PIPI学容斥(容斥定理)
-
PIPIOJ 1025 最短距离(欧几里得距离、二次函数求解)
-
PIPIOJ 1013 防水堤坝(找规律难题)
-
PIPIOJ 1018 士兵排阵(曼哈顿距离、中位数定理)
-
PIPIOJ 1044 七夕节(根号优化 / 筛法)
-
PIPIOJ 1053 哥德巴赫猜想III(筛法)
-
PIPIOJ 1156 PIPI的土地(定积分)
-
PIPIOJ 1109 PIPI的数学题VII(二分)
-
PIPIOJ 1227 PIPI的算式(二分)
分析
-
1103
- 使用同余定理,题目输入的数据超级大,一个思路使用大数来进行操作,一个就是考虑可以拆开解绝
- 从前往后拆:一个数“223” = ((((2) * 10 + 2) * 10) + 3) * 10 ,然后每次加法与乘法都可以使用这个同余定理
- 求余数需要每步都使用一次,而不是循环一使用一次,防止中间环节溢出
- 对于可能出现负数的求余方法,需要先加一个mod再减去
-
1025
- 一个计算欧几里德距离
- 对于二元一次方程组的求解,分类讨论
- 退化为1元方程或者对称轴为负数
- 当对称轴可以取得的
-
1018
- 对于曼哈顿距离,有行列无关的特性,所以对于x与y的操作可以分开
- 一个中位数定理,对于一组数据,想要获得统一到一个数,使得变化量最小,那么统一到的这个数应该是中位数
- 使用两次中位数定理,每次使用一次就使得相应数据统一,而变化量最小
- 第一次对y使用,使得所有y统一,并且变化量最小
- 第二次对x到对应的差值使用
-
1044
-
使用筛法加打表预处理存储的方法进行优化,更快
query[1] = 1; for(int i=1;i<N;i++){ for(int j=i+i;j<N;j+=i){ query[j]+=i; } }
-
使用sqrt优化,更慢
-
-
1053
-
使用埃氏筛法,可以在nloglogn就完成
void init(){ memset(p,false,sizeof(p)); for(int i=2;i<N;i++){ if(!p[i]){ idx[id++] = i;//用于保存质数 for(LL j=(LL)i*i;j<N;j+=i){ p[j] = true; } } } }
-