最大公约数
//最大公约数
int gcd(int a,int b)
{
return b ? gcd(b,a%b) : a;
}
最小公倍数
//最小公倍数
int lcm(int a,int b)
{
return a*b/gcd(a,b);
}
素数打表
v//素数打表,埃拉托斯特尼筛法
const int maxn=1e6;
bool prime[maxn];
void isprime()
{
memset(prime,0,sizeof(prime));
prime[0]=prime[1]=1;
for(int i=2;i*i
快速幂求余
//快速幂,(a^n)%mod
typedef long long ll;
ll pow_mod(ll a,ll n)
{
ll ans=1;
while(n)
{
if(n&1)
ans=ans*a%mod;
a=a*a%mod;
n>>=1;
}
return ans;
}
大数取模
//大数取模
int len=a.length();
int ans=0;
for(int i=0;i
逆元:b*c1(mod m)则c是b关于m的逆元
费马小定理:a是不能被质数p整除的正整数,则有(mod p) 可推出a*1(mod p)即a关于p的逆元为
a/b的模等于a*(b的逆元)的模
//逆元
long long quickpow(long long a,long long b)
{
if(b<0)
return 0;
long long ret=1;
a%=mod;
while(b)
{
if(b&1)
ret=ret*a%mod;
a=a*a%mod;
b>>=1;
}
return ret;
}
long long inv(long long a)
{
return quickpow(a,mod-2);
}
扩展欧几里得求解逆元
a*x1(mod m)等价于a*x+m*y=1;可以用欧几里得求一组解,(x+m)mod m即为a的逆元
//扩展欧几里得求解逆元
int exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y)
int t=y;
y=x-(a/b)*y;
x=t;
return r;//最大公约数
}
1到n逆元表
//1到n逆元表,所有逆元都求反快
long long inv[maxn];
void prepare_inv(int n,int M)
{
intv[1]=1;
for(int i=2;i<=n;i++)
{
inv[i]=(long long )(M-M/i)*inv[M%i]%M;
}
}
算数基本定理:任何一个大于1的自然数n,如果n不为质数,那么n可以分解成有限个质数的乘积,并且在不计次数的情况下,这种分解方式是唯一的;
补充:欧拉函数;
φ(N)的值,我们可以通俗地理解为小于N且与N互质的数的个数(包含1).
对于一个正整数N的素数幂分解N=P1^q1*P2^q2*...*Pn^qn.
φ(N)=N*(1-1/P1)*(1-1/P2)*...*(1-1/Pn).
//算数基本定理
map prime_factor(int n)
{
mapans;
for(int i=2;i*i<=n;i++)
{
while(n%i==0)
{
ans[i]++;
n/=i;
}
}
if(n!=1)
ans[n]=1;
return ans;
}
二进制枚举
for(int i=0;i<1<>j&1);
}
printf("\n");
}
线段相交
struct point
{
double x,y;
};
bool inter(point a,point b,point c,point d)
{//判断线段ab和cd是否相交
if(min(a.x,b.x)>max(c.x,d.x)||min(a.y,b.y)>max(c.y,d.y)||min(c.x,d.x)>max(a.x,b.x)||min(c.y,d.y)>max(a.y,b.y))
return 0;//快速排斥实验
double h,i,j,k;
h=(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
i=(b.x-a.x)*(d.y-a.y)-(b.y-a.y)*(d.x-a.x);
j=(d.x-c.x)*(a.y-c.y)-(d.y-c.y)*(a.x-c.x);
k=(d.x-c.x)*(b.y-c.y)-(d.y-c.y)*(b.x-c.x);
return h*i<=0&&j*k<=0;//跨立实验
}
多边形面积:
struct point{
int x,y;
}p;
int det(point a,point b)//叉乘
{
return a.x*b.y-a.y*b.x;
}
double area(point *ch,int m)//计算多边形的面积 ,凸多边形和非凸多边形均适用
{
double sum=0;
for(int i=1;i
凸包;
struct point{
int x,y;
}p[maxn],ch[maxn];
bool cmp(point a,point b)
{
if(a.x==b.x)
return a.y1&&det(ch[m-2],ch[m-1],p[i])>=0)
m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-2;i>=0;i--)
{
while(m>k&&det(ch[m-2],ch[m-1],p[i])>=0)
m--;
ch[m++]=p[i];
}
if(n>1)
m--;
return m;//返回凸包边上树的个数
}