2017.10.29闵神讲课DAY2(tarjan+数论)

tarjan

割点 割边 强连通分量

tarjan可以求无向图的割点、割边,有向图的强连通分量

求割点割边的方法

首先肯定用暴力枚举点(边)再深搜判断是否连通。
O(n(n+m))或者O(m(n+m))

tarjan算法可以用O(n+m)算出所有的割点割边。

割边

先构建dfs树,先建立dfs序的数组dfn[….]
一条不为割边的条件当且仅当子节点可以通过返祖边访问到比另一个子节点的祖先。
low[….]表示某个点能通过返祖边访问的dfs【】最小的点。
一条边当且仅当low【y】<=dfn[x]时不为割边。

tol=0;
void dfs(int x,edge e)
{
  dfn[x]=low[x]=++tol;
  for( x出发的每一条边 且 (x,y)属于E && (y,x )!=e )
    if( !dfn[y] ) 
      {
        dfs( y,(x,y) )
        if( low[y]<low[x] )
          low[x]=low[y];
        if( low[y]>dfn[x] ) 
         (y,x)为割边
       }
    else
     {
      if(dfn[y]<low[x])
       low[x]=dfn[y];
     }

割点

割点不一定连着割边
割边连着的不是叶子结点就是割点,但是不一定会连到所有的割点
所以不能通过割边直接得到个割点
和割边类似,low数组定义为不能经过父亲节点能到达的最小dfn值的点。
存在(x,y)使得low[y]>=dfn[x]并且x为根节点时有两个或以上的儿子 那么x就为割点。

PS:如果从2开始存边,那么两条边的异或值=1时这两条边互为反向边

强连通分量

用dfn、low记录。
low将没有任何限制 只要能访问到。就记录
在记录完dfn low后,对于一个点
if(dfn[x]==low[x]) 以x为根节点会形成一堆强连通分量。

itd=0;
void tarjan(int x)
 {
   dfn[x]=low[x]=++ind;
   ins[stack[++top]=x]=true;
   for(int i=head[x].y;i;i=e[i].next)
    if(!dfn[y=e[i].y]_
     {
       tarjan(y);
       if(low[y]<low[x])
         low[x]=low[y];
     }
     else 
      if(ins[y]&&dfn[y]<low[x])
       low[x]=dfn[y];
    if(dfn[x]==low[x])
     { 
       int k;tot++;
       do
        {
         k=stack[top--];
         ins[k]=false;
         bel[k]=tot;
        }
     }
  }

就可以将一块强连通分量缩为一个点

数论

模运算

加减乘除模运算

单位元 逆元

加法单位元:0
乘法单位元:1
x* y%p=1→x* y=z* p+1→x* y-z*p=1
所以我们可以把这个式子写成 a* x+b* p=1(道理是一样的) 其中a和b是整数
像这样 可以被表示成上面ax+bp形式的数的集合被称为x和p的线性组合
定理:gcd(x,y)是x和y的线性组合中的最小正整数。
那么一个数属于x和p的线性组合当且仅当它被gcd(x,p)整除,也就是说x有逆元当且仅当xp互质

ps:那么 我们就可以解决一个很玄学的问题了,为什么很多题目都让我们对一个非常大的质数取模而不是一个非常大的任意数,如果是一个非常大的合数,那么很多数字就没有乘法逆元,在除法计算的时候就会遇到很多不必要的麻烦。那么有些题目它要模的质数会在输入里面出现,那可能就会导致这个模数不为质数,也就是不能进行除法运算。

欧几里得算法

gcd(a,b)=gcd(a,b-a)
gcd(a,b)=gcd(b,a)
gcd(a,0)=a
易推出gcd(a,b)=gcd(a,b%a)
这个求最大公约数算法的时间复杂度是O(logn)的(因为b%a<1/2b)最坏情况下为这两个数字为斐波那契数列中连续的两个数(显然法证明23333)

扩展欧几里得算法

模运算不能有分数了,但是x依然有变成1的可能
x* y%p=1→x* y=z* p+1→x* y-z* p=1。
也就是说除以x我们只需要找到x乘谁等于1然后乘以这个数就行了,但是怎么去找这个数?
看上面那个式子,因为z是整数,所以我们可以把式子写成a*x+b*p=1,其中a和b是整数。
像这样 可以被表示成上面ax+bp形式的数的集合被称为x和p的线性组合。
定理:gcd(x,y)是x和y的线性组合中的最小正整数。
那么一个数属于x和p的线性组合当且仅当它被gcd(x,p)整除,也就是说x有逆元当且仅当xp互质
设xa+yb=d=gcd(a,b),其中x和y可能有很多对,我们的任务就是求出至少一对x和y。
根据欧几里得算法,xa+yb=d=x’(b)+y’(a%b)
最后一定有x’=1,y’=0,那么我们只需要在递归返回的时候通过x’和y’计算出x和y就行了。
a%b=a-a/b* b,那么d=y’a-(x’-a/b* y’)*b(/为整除)
待定系数就能求出x=y’,y=x’-a/b*y’。
大功告成,递归求gcd返回的同时递推一下就行
“为了让你们不觉得这玩意很恐怖我压一下码。”

这里写图片描述
然后求出来这个x之后你把它fix一下就可以辣。
当然还有一个迭代版本的,效率可能更高一些,但是我还没有理解代码,如果想学可以找你们学姐要。时间复杂度都是O(log(min(n,p)))不给证明

欧拉定理

》》欧拉函数
若x和p互质,则x^euler(p) ≡1(mod p),其中euler(p)是比p小且与p互质的数的个数,称为欧拉函数。
于是乎x^(euler(p)-1)就是x的逆元了。
于是我们可以用倍增快速幂来求。
时间复杂度为O(logp),但是logp同时也是下界,所以可能会比扩欧慢一些,但是写起来方便.

LUCAS定理

例题:

要求:p为质数

C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)(p为质数)
要背下来!

ll C( ll n,ll m)
{
return n<=p&&m<=p? C[n][m] : C[n%p][m%p]*C()
}

证明:以2进制为例,假如以二进制输入,那么我们可以发现:它就是把每一位拆开,从最低为开始求组合数,将其余位继续递归。
O(p^2+logn)
例题:BZOJ4591

中国剩余定理

只在模数的所有因子都互质的情况下才是

若我们已知m个互不相同的模数pi(i=1…m)那么一个数模这几个数的余数(a1,a2,…,am)与这个数模这m个数P的乘积r存在一一对应关系。
设Mi=P/pi(整除),ti=Mi^-1(mod pi),那么
r=sum{ai*ti*Mi}%P
有了这个式子,我们就可以分别求出来答案模P的质因子的结果然后用这个式子将最终答案还原即可。

欧拉筛(线性筛)

我们介绍一种叫做欧拉筛的筛法,他能够通过独特的“每个合数会被不重不漏”地筛一遍的方法达到O(n)的效率,因此也称为线性筛。
这里写图片描述

BSGS

问题:求满足a^x≡y(mod p)的最小的x,ap互质。
设x=im+j(0≤j<m)
那么a^(im)≡y*a^(-j)(mod p)
枚举j,将所有的y*a^(-j)放入哈希表中。
然后枚举i,在哈希表中查找a^(-im)是否存在。
第一个匹配的im+j是最小解(因为从小到大枚举i)。
BSGS是一个叫做meet-in-the-middle算法的实例。

PS:课后老刘案例的网上求逆元的玄学方法:

1、费马小定理(自行度娘)
2、递推法
这里写图片描述

非常神奇的O(n)算法,很实用。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 、 1资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READmE.文件(md如有),本项目仅用作交流学习参考,请切勿用于商业用途。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值