2019/4/7 奇奇怪怪的笔记

狄利克雷卷积 

  • \(μ∗1=ϵ\),莫比乌斯反演

  • \(Id=φ∗1⇒φ=μ∗Id\)

  • \(d=1∗1⇒1=μ∗d\)

  • \(σ=Id∗1⇒Id=μ∗σ\)

  • \(σ=φ∗d\)

一些性质?

  • \(\gcd(a^k-1,b^k-1)=x^{gcd(a,b)}-1\)

  • \(\alpha^{\phi(p)}≡1(mod p)\)

  • \(gcd(Fib(a),Fib(b))=Fib(gcd(a,b))\)

  • $n|m \Leftrightarrow Fib_n|Fib_m $

  • \(d(ij)=∑_{p|i}∑_{q|j}[gcd(p,q)=1]\)

  • \(σ_0(n_1n_2...n_m)=\sum_{a_1|n_1}\sum_{a_2|n_2}...\sum_{a_m|n_m}\prod_{1\leq i <j\leq m} [gcd(a_i,a_j)=1 ]\)

  • \(σ(ij)=∑_{p|i}∑_{q|j}[gcd(p,q)=1]\frac{i}{p}q\)

  • \(∑^n_{i=1}μ^2(i)=∑_{i⩾1}μ(i)⌊\frac{n}{i^2}⌋\)

广义容斥原理

二项式反演

  • \(b_k=\sum_{i=0}^k\binom{k}{i}a_i \\\Rightarrow a_k=\sum_{i=0}^k(-1)^{k-i}\binom{k}{i}b_i\)
  • \(b_k=\sum_{i=k}^n \binom{i}{k}a_i\\\Rightarrow a_k=\sum_{i=k}^n(-1)^{i-k}\binom{i}{k}b_i\)

简单证明:

\(\binom{n}{i}\binom{i}{j}=\binom{n}{j}\binom{n-j}{i-j}\)

对于一式

\(\sum_{i=0}^k(-1)^{k-i}\binom{k}{i}b_i=\sum_{j=0}^n a_j (\sum_{i=j}^k(-1)^{k-i}\binom{k}{j}\binom{k-j}{i-j})\)

考虑二项式定理:

\(\sum_{i=j}^{k}(-1)^{k-i}\binom{k-j}{i-j}=[k-j=0]\)

对于二式

\(\sum_{i=k}^n(-1)^{i-k}\binom{i}{k}b_i=\sum_{j=k}^{n} a_j (\sum_{i=k}^{j}(-1)^{i-k}\binom{i}{k}\binom{j}{i})\)

\(\sum_{i=k}^{j}(-1)^{i-k}\binom{i}{k}\binom{j}{i}=\binom{j}{k}\sum_{i=k}^{j}(-1)^{i-k}\binom{j-k}{i-k}=[j=k]\)

核心是二项式定理,然后记忆方法就是考虑上式和下式其实之差一个\((-1)^{i-k}\)

广义容斥原理

\(A_i\)表示含有性质\(i\)的元素集合

\(b_m\)表示恰好含有\(m\)种性质的元素个数

\(a_m\)表示至少含有\(m\)种性质的元素的元次

\[a_m=\sum_{I\in C(n,m)}|\bigcap_{i\in I}^{} A_i|
\]

发现,含有\(m+k\)个性质的元素被\(a_m\)记录了\(\binom{m+k}{m}\)次

所以\(a_m=\sum_{i=m}^{n} b_i\binom{i}{m}\),根据二项式反演

Prufer序列与Cayley公式

Prufer序列

与无根树一一对应

定义无根树中度数为\(1\)的点是叶子节点。

求Prufer序列

找到编号最小的叶子节点\(x\),在Prufer序列中添加与\(x\)相连的点,然后删除\(x\)

不断重复,直到只剩下\(2\)个节点。

具体可以用一个\(set\),实时维护度数为\(1\)的点。

求无根树

记点集为\(V\),每次取出Prufer序列第一个元素\(x\),然后在\(V\)中找到最小的没有在Prufer序列中出现的元素\(y\),在\(x\)和\(y\)之间连一条边,然后在Prufer序列中删除\(x\),点集\(V\)中删除\(y\),不断重复,直到\(V\)中剩下两个点,最后在这两个点中连一条边。

具体也可以用一个\(set\),实时维护Prufer序列中没有出现过的点。

Cayley公式

\(n\)个点有标号的无根树的个数:\(n^{n−2}\)。

度数为\(d_i\)的点在序列中出现了\(d_i\)次

\(n\)个点,第\(i\)个点的度数为\(d_i\)的无根树个数:\(\frac{(n−2)!}{∏^{n}_{i=1}(d_i−1)!}\)

千年不写的Treap

Code

  1. #define lc c[x][0]
  2. #define rc c[x][1]
  3. int c[MN][2],siz[MN],cnt[MN],rnd[MN],val[MN];
  4. int sz,rt;
  5. inline void update(int x){siz[x]=cnt[x]+siz[lc]+siz[rc];}
  6. inline void lturn(int &x)//旋右儿子
  7. {
  8. int ch=rc;rc=c[ch][0];c[ch][0]=x;
  9. siz[ch]=siz[x];update(x);x=ch;
  10. }
  11. inline void rturn(int &x)//旋左儿子
  12. {
  13. int ch=lc;lc=c[ch][1];c[ch][1]=x;
  14. siz[ch]=siz[x];update(x);x=ch;
  15. }
  16. void Ins(int &x,int v)
  17. {
  18. //注意点,siz是在递归前加的,然后每一步都要考虑是否满足堆的性质
  19. if(!x){x=++sz;lc=rc=0;siz[x]=cnt[x]=1;val[x]=v;rnd[x]=rand();return;}
  20. siz[x]++;if(val[x]==v){cnt[x]++;return;}
  21. if(v<val[x]){Ins(lc,v);if(rnd[lc]<rnd[x]) rturn(x);}
  22. else {Ins(rc,v);if(rnd[rc]<rnd[x]) lturn(x);}
  23. }
  24. int Rnk(int x,int v)
  25. {
  26. //查询v值在x子树内的排名
  27. if(val[x]==v) return siz[lc]+1;
  28. if(val[x]>v) return Rnk(lc,v);
  29. else return siz[lc]+cnt[x]+Rnk(rc,v);
  30. }
  31. int Kth(int x,int k)
  32. {
  33. //查询x子树内排名为k的节点的值
  34. if(k<=siz[lc]) return Kth(lc,k);
  35. else if(k>siz[lc]+cnt[x]) return Kth(rc,k-siz[lc]-cnt[x]);
  36. else return val[x];
  37. }
  38. void Del(int &x,int v)
  39. {
  40. //找到点后,把它旋到底(或只有一个孩子),然后删除
  41. if(!x) return;
  42. if(val[x]==v)
  43. {
  44. if(cnt[x]>1){cnt[x]--;siz[x]--;return;}
  45. if(lc*rc==0) x=lc+rc;
  46. else if(rnd[lc]<rnd[rc]) rturn(x),Del(x,v);
  47. else lturn(x),Del(x,v);
  48. }
  49. else siz[x]--,Del(v>val[x]?rc:lc,v);
  50. }
  51. int Pre(int x,int v)
  52. {
  53. //查询v在x子树内的前驱
  54. if(!x) return 0;int q;
  55. if(val[x]<v) return (q=Pre(rc,v))?q:x;
  56. else return Pre(lc,v);
  57. }
  58. int Suf(int x,int v)
  59. {
  60. //查询v在x子树内的后缀
  61. if(!x) return 0;int q;
  62. if(val[x]>v) return (q=Suf(lc,v))?q:x;
  63. else return Suf(rc,v);
  64. }

超级可爱的Splay

Code

  1. #define rtf 400004
  2. #define rt c[rtf][0]
  3. //这样定义就可以解决rt在rtt中的更新问题
  4. using namespace std;
  5. int n,sz[MN],c[MN][2],tn,fa[MN],val[MN],sum[MN],cnt;
  6. void update(int x){sz[x]=sz[c[x][0]]+sz[c[x][1]]+sum[x];}
  7. void rotate(int x)
  8. {
  9. int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;fa[y]=x,fa[x]=z,fa[c[x][r]]=y;
  10. c[z][c[z][1]==f]=x,c[y][l]=c[x][r],c[x][r]=y;update(y);
  11. }
  12. void splay(int x,int y)
  13. {
  14. //旋转到y的子节点
  15. for(int f;fa[x]!=y;rotate(x))
  16. if(fa[f=fa[x]]!=y)rotate(c[fa[f]][1]==f^c[f][1]==x?x:f);
  17. update(x);
  18. }
  19. void ins(int f,int ty,int v)
  20. {
  21. //这里的当前节点就是c[f][ty],在递归前就要更新siz,最后要splay一下
  22. if(!c[f][ty]){fa[c[f][ty]=++tn]=f;val[tn]=v;sum[tn]=1;splay(tn,rtf);return;}
  23. if(v==val[c[f][ty]]){sum[c[f][ty]]++;splay(c[f][ty],rtf);return;}
  24. ++sz[f=c[f][ty]];
  25. ins(f,v>val[f],v);
  26. }
  27. void del(int f,int ty,int v)
  28. {
  29. //当前点就是c[f][ty],最后要Splay一下
  30. //把c[f][ty]旋到根,把后继旋到它的右儿子,然后把根的左儿子继承给右儿子
  31. //同样在递归前修改siz
  32. if(val[c[f][ty]]==v)
  33. {
  34. int x=c[f][ty];
  35. if(sum[x]>1){sum[x]--,splay(x,rtf);return;}int tmp;
  36. if(!(c[x][0]*c[x][1])){c[f][ty]=c[x][0]+c[x][1],fa[c[x][c[x][1]!=0]]=f;return;}
  37. for(tmp=c[x][1];c[tmp][0]!=0;tmp=c[tmp][0]);
  38. splay(x,rtf),splay(tmp,rt);
  39. c[tmp][0]=c[x][0],rt=tmp,fa[c[x][0]]=tmp,fa[tmp]=rtf;update(tmp);return;
  40. }
  41. --sz[f=c[f][ty]];del(f,v>val[f],v);
  42. }
  43. int findk(int x,int k)
  44. {
  45. //查询x子树内第k大的节点
  46. if(k<=sz[c[x][0]])return findk(c[x][0],k);
  47. else if(k>sz[c[x][0]]&&k<=sz[c[x][0]]+sum[x]){splay(x,rtf);return val[x];}
  48. else return findk(c[x][1],k-=sz[c[x][0]]+sum[x]);
  49. }
  50. int getk(int x,int k)
  51. {
  52. //查询x子树内小于权值k的节点数量
  53. if(!x)return 0;
  54. if(val[x]>=k)return getk(c[x][0],k);
  55. else return sz[c[x][0]]+sum[x]+getk(c[x][1],k);
  56. }
  57. int pre(int x){int tmp=getk(rt,x);return findk(rt,tmp);}
  58. int suf(int x){int tmp=getk(rt,x+1)+1;return findk(rt,tmp);}

写起来最舒服的FHQ

Code

  1. //只要会三个函数:random,split,merge
  2. class fhq
  3. {
  4. #define MN 100005
  5. private:
  6. int sz;
  7. int val[MN],pri[MN],ls[MN],rs[MN],siz[MN],cnt;
  8. inline unsigned int random()
  9. {
  10. static unsigned int x=23333;
  11. return x^=x<<13,x^=x>>17,x^=x<<5;
  12. }
  13. inline void combine(int x){siz[x]=1+siz[ls[x]]+siz[rs[x]];}
  14. public:
  15. int rt;
  16. int Merge(int rt1,int rt2)
  17. {
  18. if(!rt1||!rt2) return rt2+rt1;
  19. if(pri[rt1]<pri[rt2])
  20. {
  21. rs[rt1]=Merge(rs[rt1],rt2);
  22. combine(rt1);return rt1;
  23. }
  24. else
  25. {
  26. ls[rt2]=Merge(rt1,ls[rt2]);
  27. combine(rt2);return rt2;
  28. }
  29. }
  30. void Split(int x,int k,int &rt1,int &rt2)
  31. {
  32. if(!x)return(void)(rt1=rt2=0);
  33. if(k<=siz[ls[x]]) Split(ls[x],k,rt1,ls[x]),combine(x),rt2=x;
  34. else Split(rs[x],k-siz[ls[x]]-1,rs[x],rt2),combine(x),rt1=x;
  35. }
  36. int Rank(int x,int v)
  37. {
  38. if(!x) return 0;
  39. if(v<val[x]) return Rank(ls[x],v);
  40. else return siz[ls[x]]+Rank(rs[x],v)+1;
  41. }
  42. int Kth(int k)
  43. {
  44. register int rt1,rt2,rt3,c;
  45. Split(rt,k,rt1,rt2);Split(rt1,k-1,rt3,c);
  46. rt=Merge(rt3,Merge(c,rt2));
  47. return val[c];
  48. }
  49. void Insert(int v)
  50. {
  51. val[++sz]=v;pri[sz]=random(),siz[sz]=1;
  52. register int rk=Rank(rt,v),rt1,rt2;
  53. Split(rt,rk,rt1,rt2);
  54. rt=Merge(Merge(rt1,sz),rt2);
  55. }
  56. void Delete(int v)
  57. {
  58. register int rk=Rank(rt,v),rt1,rt2,rt3,c;
  59. Split(rt,rk,rt1,rt2);Split(rt1,rk-1,rt3,c);
  60. rt=Merge(rt3,rt2);
  61. }
  62. }T;

可持久化FHQ

Code

  1. int NewNode(int x)
  2. {
  3. ++sz;
  4. val[sz]=val[x];pri[sz]=pri[x];ls[sz]=ls[x];
  5. rs[sz]=rs[x];siz[sz]=siz[x];
  6. return sz;
  7. }
  8. int Merge(int rt1,int rt2)
  9. {
  10. if(!rt1||!rt2) return rt2|rt1;
  11. if(pri[rt1]<pri[rt2])
  12. {
  13. register int p=NewNode(rt1);
  14. rs[p]=Merge(rs[rt1],rt2);
  15. combine(p);return p;
  16. }
  17. else
  18. {
  19. register int p=NewNode(rt2);
  20. ls[p]=Merge(rt1,ls[rt2]);
  21. combine(p);return p;
  22. }
  23. }
  24. void Split(int x,int k,int&rt1,int&rt2)
  25. {
  26. if(!x) return (void)(rt1=rt2=0);
  27. if(k<=siz[ls[x]])
  28. {
  29. rt2=NewNode(x);
  30. Split(ls[x],k,rt1,ls[rt2]);
  31. combine(rt2);
  32. }
  33. else
  34. {
  35. rt1=NewNode(x);
  36. Split(rs[x],k-siz[ls[x]]-1,rs[rt1],rt2);
  37. combine(rt1);
  38. }
  39. }

Link_Cut_Tree

大部分时候都是有根树,也只查询到根的路径,所以根本不需要换根,但是还是有必要会写\(mkrt\)

Code

  1. class Link_Cut_Tree
  2. {
  3. #define MN 300005
  4. private:
  5. int N,fa[MN],c[MN][2],st[MN],val[MN],X[MN];
  6. bool rev[MN];
  7. inline bool nrt(int x){return c[fa[x]][0]==x||c[fa[x]][1]==x;}
  8. inline void Rev(int x){rev[x]^=1;std::swap(c[x][0],c[x][1]);}
  9. inline void up(int x){X[x]=X[c[x][0]]^X[c[x][1]]^val[x];}
  10. inline void down(int x){if(x&&rev[x])Rev(c[x][0]),Rev(c[x][1]),rev[x]=0;}
  11. #define get(x) (c[fa[x]][1]==x)
  12. inline void rotate(int x)
  13. {
  14. int y=fa[x],z=fa[y],l=get(x),r=l^1;if(nrt(y))c[z][get(y)]=x;fa[x]=z;
  15. c[y][l]=c[x][r];fa[c[x][r]]=y;c[x][r]=y;fa[y]=x;up(y);
  16. }
  17. inline void Splay(int x)
  18. {
  19. //最容易写错的部分!
  20. static int top,q[MN];q[top=1]=x;register int i;
  21. for(i=x;nrt(i);i=fa[i]) q[++top]=fa[i];for(;top;--top) down(q[top]);
  22. for(;nrt(x);rotate(x))if(nrt(fa[x])) rotate(get(fa[x])^get(x)?x:fa[x]);up(x);
  23. }
  24. #undef get
  25. //acs的时候一定要up(x)!
  26. inline void access(int x){register int i;for(i=0;x;x=fa[i=x])Splay(x),c[x][1]=i,up(x);}
  27. inline void mkrt(int x){access(x);Splay(x);Rev(x);}
  28. //fdrt后一定要Splay一下!还有就是找根的时候要pushdown
  29. inline int fdrt(int x){access(x),Splay(x);for(;c[x][0];down(c[x][0]),x=c[x][0]);Splay(x);return x;}
  30. inline void Split(int x,int y){mkrt(x);access(y);Splay(y);}
  31. public:
  32. inline void init(int n){register int i;for(i=1;i<=n;++i) val[i]=X[i]=read();}
  33. //如果是有根树:直接fa[x]=y
  34. void Link(int x,int y){mkrt(x);if(fdrt(y)!=x)fa[x]=y;}
  35. //如果是有根树:acs(x);Splay(x);fa[c[x][0]]=0;c[x][0]=0;up(x);
  36. void Cut(int x,int y){Split(x,y);if(c[y][0]==x&&!c[x][1])c[y][0]=fa[x]=0,up(y);}
  37. inline int Query(int x,int y){if(x==y) return val[x];Split(x,y);return X[y];}
  38. inline void Modify(int x,int V){Splay(x);val[x]=V;up(x);}
  39. #undef MN
  40. }T;

Blog来自PaperCloud,未经允许,请勿转载,TKS!

Note_4.7的更多相关文章

  1. note_4.10

    单位根反演 \[ \frac{1}{k}\sum_{i=0}^{k-1}\omega_k^{in}=[k|n] \] 所以 \[ \begin{equation} \begin{split} \sum ...

  2. Note_4.9

    2019/4/9 奇奇怪怪的笔记 关于代码,基本上是现写的,可能连编译都过不了 因为是简单算法场,所以就很不走心了昂,/小纠结 图论相关  最小生成树 prim,kruskal 最小生成树的切割性质 ...

  3. Note_4.1

    2019/4/1 奇奇怪怪的笔记 多项式除法 问题描述 给定\(n\)次多项式\(A(x)\)和\(m\)次多项式\(B(x)\) 求: \[ A(x)=B(x)*C(x)+R(x) \] 我们要求\ ...

  4. boost::xml——基本操作以及中文乱码解决方案

    下面是本人使用boost库的xml部分的基础操作,并且解决对于大家使用boost库读写中文xml内容出现的乱码问题. 1.实现boost库xml基本操作2.解决boost对xml中中文乱码问题3.实现 ...

  5. Spring MVC(3)Spring MVC 高级应用

    一.Spring MVC 的数据转换和格式化 前面的应用,都只是用HandlerAdapter去执行处理器. 处理器和控制器不是一个概念,处理器是在控制器功能的基础上加上了一层包装,有了这层包装,在H ...

  6. Spring MVC(2)Spring MVC 组件开发

    一.控制器接收各类请求参数 代码测试环境: 接收各类参数的控制器--ParamsController package com.ssm.chapter15.controller; @Controller ...

随机推荐

  1. 一个 Vim 重度用户总结的 vim 超全指南

    我本人是 Vim 的重度使用者,就因为喜欢上这种双手不离键盘就可以操控一切的feel,Vim 可以让我对文本的操作更加精准.高效. 对于未使用过 Vim 的朋友来说,可能还无法体会到这种感觉.由于使用 ...

  2. mysql order by基于时间的盲注

    order by后面的注入,一般先尝试报错注入,无报错的时候可以通过rand(ture)和rand(false)来进行bool型盲注,但是今天遇到完全没有数据回显的(也就是数据库中没有数据)情况,这就 ...

  3. Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))

    off by one(栈)? 将源字符串复制到目标缓冲区可能会导致off by one 1.源字符串长度等于目标缓冲区长度. 当源字符串长度等于目标缓冲区长度时,单个NULL字节将被复制到目标缓冲区上 ...

  4. Android 常用开源库总结(持续更新)

    前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关于Android 优秀的开源库,也可以在下面留言. 一 .基本控件 TextView HTextView 一 ...

  5. Qt环境搭建

    下载 qtcreator:http://download.qt.io/official_releases/qtcreator/ 编译器(mingw):http://download.qt.io/dev ...

  6. 【转】Anaconda安装与使用

    PS:这还是17年一次数据挖掘训练营使用的软件 [转至]https://blog.csdn.net/m0_37605642/article/details/98726766 安装和配置 1.在官网或清 ...

  7. mysql数据库备份,主从复制及半同步复制

    1.使用mysqldump备份数据库并通过备份及二进制日志还原数据(备份完后再写入数据,然后再删库) mysqldump -A --single-transaction -F --master-dat ...

  8. Flink 原理(六)——异步I/O(asynchronous I/O)

    1.前言 本文是基于Flink官网上Asynchronous  I/O的介绍结合自己的理解写成的,若有不正确的欢迎大伙留言交流,谢谢! 2.Asynchronous  I/O简介 将Flink用于流计 ...

  9. .net core自定义读取配置文件

    新建完成后项目目录下有个 appsettings.json { "Logging": { "LogLevel": { "Default": ...

  10. SOAP知识点

    SOAP简介: SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换. 或者更简单地说:SOAP 是用于访问网络服务的协议. 1.什么是 SOAP? SOAP 指简易对象访 ...