徐州summer camp
待学课程 | 是否已学 |
---|---|
后缀数组 | false |
线段树 | false |
KMP以及拓展KMP | false |
RMQ | false |
背包九讲 | false |
exgcd | true |
梅森素数 | false |
网络流 | false |
set | false |
欧筛 | true |
高斯消元 | false |
FFT | false |
Miller-Rabin素数测试 | false |
欧拉图 | ing |
哈密顿图 | ing |
计算几何 | ing |
欧拉图
- 性质
欧拉回路的存在性判定:当且仅当无向图联通且每个顶点度数都为偶数时,此图为欧拉图。
欧拉图的判定: 欧拉回路至多允许两个度为基数的定点出现。 - 实现模板
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
const int maxn=100010;
int head[maxn],ver[maxn],nt[maxn],tot;
int st[maxn],ans[maxn];
bool vis[maxn];
int n,m,top,t;
void add(int x,int y)
{
ver[++tot]=y,nt[tot]=head[x],head[x]=tot;
}
void euler(void)
{
st[++top]=1;
while(top>0)
{
int x=st[top],i=head[x];
while(i&&vis[i]) i=nt[i];
if(i)
{
st[++top]=ver[i];
vis[i]=vis[i^1]=true;
head[x]=nt[i];
}
else
{
top--;
ans[++t]=x;
}
}
}
int main(void)
{
cin>>n>>m;
tot=1;
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
euler();
for(int i=t;i;i--) printf("%d\n",ans[i]);
return 0;
}
欧拉筛法
- 原理
每个数均被最小质因数所筛掉,并且只被筛一次,达到线性筛的目的。 - 模板
const int MAXN=1000000;
int prime[MAXN];
bool isprime[MAXN];
void oula()
{
int count=1;
for(int i=2;i<=MAXN;i++){
if(!isprime[i]) prime[count++]=i;
for(int j=1;j<count;j++){
if(i*prime[j]>MAXN) break;
isprime[i*prime[j]]=1;
if(!i%prime[j]) break;
}
}
}
exgcd
- 原理
首先我们要先了解贝祖定理
即如果a、b是整数,那么一定存在整数x、y使得ax+by=gcd(a,b)。
换句话说,如果ax+by=m有解,那么m一定是gcd(a,b)的若干倍。
则我们可以求对于gcd(a,b)的解x,y,当x=1,y=0时有表达式a1+b0=gcd(a,b),
但此时a,b不为当初的那个a,b而是经过gcd转化过的a,b可以通过gcd的递归反向转化出原来的x,y
这时我们可以试着去寻找这两个相邻状态的关系:
首先我们知道:a%b=a-(a/b)b;带入:
bx1 + (a-(a/b)b)y1
= bx1 + ay1 – (a/b)by1
= ay1 + b(x1 – a/by1) = gcd 发现 x = y1 , y = x1 – a/by1
这样就可以求值了。
(此部分参考https://blog.csdn.net/destiny1507/article/details/81750874这位博主的文章,讲的很详细。)
- 用途
求最小正整数的解
对于原式ax+by=m而言,我们可以求得特解x1,y1
(此x1,y1是满足于a1*x1+b1*y1=gca(a,b)的解)
可以简单推导出a*(x1+k*b/gcd)+b*(y1-k*a/gcd)=m,则x,y通解为x1+k*b,y1-k*a(k可以为任意整数)
x=(x%b+b)%b,y可根据a*x+b*y=m求出,对于y的最小正整数解同理可得。 - 模板
int exgcd(int a,int b,int &x,int &y)
{
if(!b){
x=1,y=0;
return a;
}
int ans=exgcd(b,a%b,x,y);
int temp=x;
x=y,y=temp-a/b*y;
return ans;
}
计算几何
点线面的运算
- 点积和叉积
- 计算线段交
进行两次跨立实验即可 - 计算三角形外心
- 欧拉公式计算多面体
(平面图)若一个图能画在平面上使它的边除了在顶点处外互不相交,则称该图为平面图,或称该图能嵌入平面的。
学多少更多少吧,最近需要学的知识有点多,只能爆肝了