算法题个人思路总结

数学

1.设A与C是互质的两个数,求B,使得A*B=1(mod C)。

解:由于gcd(A,C)=1,因此利用扩展欧几里德函数可以找到a*A+c*C=1,即a*A=1(mod C)。我们取B=a即可。

 

2.求$\sum_{i=1}^n{\frac{1}{i}}$的上下界。

解:$\ln \left( n+1 \right) = \int_1^{n+1}{\frac{1}{x}dx}\le \sum_{i=1}^n{\frac{1}{i}}\le 1+\int_1^n{\frac{1}{x}dx}=1+\ln \left( n \right) $。

 

3.求形如$\sum_{i=1}^n{i^{\alpha}}$的上下界,其中α>=0。

解:$1+\frac{1}{\alpha +1}\left( n^{\alpha +1}-1 \right) =1+\int_1^n{x^{\alpha}dx}\le \sum_{i=1}^n{i^{\alpha}}\le \int_1^{n+1}{x^{\alpha}dx}=\frac{1}{\alpha +1}\left( \left( n+1 \right) ^{\alpha +1}-1 \right) $。

 

4.对于所有i<=L,求所有i的素因子。

解:利用欧拉筛,每次都只会处理一次合数,处理的时候将所用到的素数填入。时间复杂度为O(L)。

 

5.因子数目最多的数。

解:<=1e1, 6, 4

  <=1e2,60,12

  <=1e3,840,32

  <=1e4,7560,64

  <=1e5,83160,128

  <=1e6,720720,240

  <=1e7,8648640,448

  <=1e8,73513440,768

 

6.对多项式进行卷积 。

解:快速傅立叶变换。

 

7.求a/b向上取整

解:(a+b-1)/b。

 

8.对浮点数f进行四舍五入

解:(int)(f + 0.5)

 

9.取整数i的二进制最后一位。

解:i&-i。

数据结构

1.要求大批量查询区间最大值最小值。

解:1.如果区间不会被修改,则使用ST算法在长度为n的区间上以时空复杂度O(nlog2n)做预处理,并以O(1)时间复杂度做查询。

  2.如果区间会被修改,则使用线段树进行处理。

 

2.在一株树上统计路径信息。

解:使用LCT,所有操作时间复杂度均为O(log2n)。

 

3.数据范围较大,但实际数据较少。

解:离散处理。

 

4.要求多次处理树上差分,每个结点对应一组值。

解:树上每个结点对应一个持久化线段树,并且子结点的持久化线段树在父结点的持久化线段树上创建。

 

5.给定n大小不变区间,区间值最大值为M,m次查询区间第k小。

解:将区间视为一株树,下标i对应i+1的父结点,问题相当于在树上做差分。查询区间[l,r]上第k小,等价于查询持久化线段树r与持久化线段树l-1的差分对应的线段树上第k小元素。时间复杂度为O((n+m)log2(M))。

 

6.给定一株含n个结点的树,m次查询lca。

解:1.先利用dfs将树压成区间,之后利用st处理区间最小值和最大值。时间复杂度为O(2nlog2(n)+m)。

  2.如果允许离线处理,则利用tarjan算法可以在O(n+m)时间复杂度内求出。

 

7.给定长度为n的区间A,m次询问求子区间值的加总。

解:1.如果区间不会被修改,那么可以用差分,创建新的数组s,其中s[i]=A[0]+...+A[i],则A[i]+...+A[j]=s[j]-s[i-1]。时间复杂度为O(n+m)。

  2.如果区间会被修改,可以使用线段树。时间复杂度为O(n+mlog2n)。

 

8.给定长度为n的数组,给定m个请求,每个请求要求查询一段区间中不同的值的数目。

解:莫队算法,暴力得AC,时间复杂度为O(n+n√m)。

 

9.给定一株树,每个结点对应一个值。求某个结点作为根的子树下不同的值的数目。

解:树上莫队,将树通过dfs压成数组,子树代表的是一段连续区间,之后莫队。

 

 

动态规划 

1.dp[i+1]=f(dp[i]),其中f是线性函数,求dp[k],k很大。

解:将f表示为矩阵,之后对矩阵做快速幂乘求f^k,最后应用于dp[0],则dp[k]=f^k(dp[0])。时间复杂度为O(n^3*log2(k)),n为矩阵大小(dp[i]的维度)。

 

字符串

1.给定长度为n的字符串,m次判断两个子串是否相同。

解:在字符串上进行hash处理,之后以O(1)实际复杂度取子串哈希值并进行比较。实际复杂度为O(n+m)。注意要小心生日悖论,如果哈希范围为k,则只需要sqrt(k)个不同子串就有1/2以上的概率使得存在两个子串拥有相同哈希值,这时候可以多次进行哈希,从而提高k的范围。

 

2.判断长度为n的字符串中最长回文。

解:1.哈希:利用哈希可以在O(1)时间复杂度内判断某个子串是否为回文,如果以i为左边界的最长回文为s[i,j],则以i+1为左边界的最长回文至少为s[i-1,j-1],因此判断总次数为2*n。

  2.manacher算法,时空复杂度为O(n)。

  3.回文树,时空复杂度为O(n*α),α为字符集大小。

 

3.判断长度为n与m的字符串a与b的最长相同子串。

解:后缀自动机。

 

几何

1.平面上n个矩形,求被这些矩形覆盖的面积。

解:先对矩形按照矩形底部y坐标进行从小到大排序。之后用扫描线算法从左到右扫描矩形左右边界。总的时间复杂度为O(n^2)。

 

2.给定三个非共线点,计算三角形面积。

解:设三点为A,B,C,则求向量AB与AC之后计算|ABxAC|/2即为三角形面积,其中x表示外积。

 

3.给定向量a,b,判断b与a的关系。

解:计算axb,若为正数,则表示b在a的逆时针方向,若为负数,则b在a的顺时针方向,否则a与b共线。

 

4.给定三角形ABC,和一个点p,判断点p是否处于ABC内部(包含边上)。

解:计算ABp,ACp,BCp的面积之和,如果等同于ABC则p在ABC内部,否则在ABC外部。

 

5.计算凸多边形的面积。

解:凸多边形可以表示为多个三角形的合并。

 

6.判断点p与向量AB的关系。

解:相当于判断向量Ap与向量AB的关系。

 

7.判断点p在线段AB上。

解:要保证p于向量AB共线,之后还要保证min(A.x,B.x)<=p.x<=max(A.x,B.x),且min(A.y,B.y)<=p.y<=max(A.y,B.y)。

 

8.三角形的心脏。

解:1.外心(外接圆圆心),三条中垂线交点。

  2.内心(内接圆圆心),三条角平分线交点。

  3.重心,三条中线交点,三条中线将三角形切分为6个面积相同的三角形,过重心任意一条划线,将三角形切分为面积相同的两部分。

 

9.计算两条直线交点,直线分别由两个不同顶点P1,P2与P3,P4给出。

解:利用代数几何的思想。直线P1P2上的任意点可以由f(a)=(1-a)P1+ap2给出,同理P3,P4上的点可以由g(b)=(1-b)P3+bP4给出,当0<=a,b<=1时,f(a)与g(a)分别落在P1P2与P3P4所代表的线段上。

  而P1P2与P3P4的交点则由等式f(a)=g(b)给定。

  设Pi=(xi,yi),则f(a)=g(b)可以展开为二元一次方程组:

$$
\begin{cases}
\left( x_2-x_1 \right) a+\left( x_3-x_4 \right) b=x_3-x_1\\
\left( y_2-y_1 \right) a+\left( y_3-y_4 \right) b=y_3-y_1\\
\end{cases}
\\
\Rightarrow \left[ \begin{matrix}
x_2-x_1& x_3-x_4\\
y_2-y_1& y_3-y_4\\
\end{matrix} \right] \left[ \begin{array}{c}
a\\
b\\
\end{array} \right] =\left[ \begin{array}{c}
x_3-x_1\\
y_3-y_1\\
\end{array} \right]
\\
\Rightarrow \left[ \begin{array}{c}
a\\
b\\
\end{array} \right] =\left[ \begin{matrix}
x_2-x_1& x_3-x_4\\
y_2-y_1& y_3-y_4\\
\end{matrix} \right] ^{-1}\left[ \begin{array}{c}
x_3-x_1\\
y_3-y_1\\
\end{array} \right]
$$

对于计算逆矩阵,可以利用:

$$
A^{-1}=\left( \det A \right) ^{-1}A^V
$$

其中A^V表示矩阵A的伴随矩阵,对于二元矩阵有:

$$
\left[ \begin{matrix}
a& b\\
c& d\\
\end{matrix} \right] ^V=\left[ \begin{matrix}
d& -b\\
-c& a\\
\end{matrix} \right]
$$

若detA=0,则表示式子有多个解或无解,这时候两条直线必定平行。

解出a与b后,可以利用f(a)或g(b)获得交点。

 

10.判断两条线段是否相交。

解:先利用问题9的解法计算两条线段的交点,得到a与b后验证0<=a,b<=1即可。或者算出交点后判断交点是否在两条线段上即可。

内存使用

1.n个槽,将m个对象存入到这n个槽中。

解:利用动态表或者链表均能以O(n+m)的时空复杂度内完成。

 

2.n个空间,使用前需要初始化,如何多次复用。

解:额外分配n个空间,记录每个对于空间上次初始化时的版本,之后访问该空间之前,先比较版本,如果版本不同,则先初始化后更新版本。访问的时间复杂度为O(1),但是常数较大。

 

转载于:https://www.cnblogs.com/dalt/p/9173085.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值