#快速幂#
int qpow(int x,int k,int p)
{
int ans=1;
for(;k;x=x*x%p,k=k>>1)
if(k&1) ans=(ans*x)%p;
return ans;
}
#线性筛#
void get_prime(bool mk[],int p[],int mn[],int n)
{
for(int i=2;i<=n;i++)
{
if(!mk[i]) p[++p[0]]=i,mn[i]=p[0];
for(int j=1;j<=p[0]&&i*p[j]<=n;j++)
{
mk[i*p[j]]=1;
mn[i*p[j]]=j; //最小质因数
if(i%p[j]==0)break;
}
}
}
#线性求欧拉函数#
void get_phi()
{
phi[1]=1;
for(int i=2;i<=N;i++)
{
if(!mk[i]) p[++cnt]=i,phi[i]=i-1;//i为素数
for(int j=1;j<=cnt&&p[j]*i<=N;j++)
{
mk[i*p[j]]=1;
if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j];break;}
//如果i%p=0 phi(i*p)=p*phi(i) 证明见下方
else phi[i*p[j]]=phi[i]*(p[j]-1);//欧拉函数为积性函数
}
}
}
先贴个链接。。有时间补上 证明
#线性求莫比乌斯函数#
跟上面差不多。。。
void get_mul(int n)
{
mul[1]=1;
for(int i=2;i<=n;i++)
{
if(!s[i]){p[++head]=i,mul[i]=-1;}
for(int j=1;j<=head&&p[j]*i<=n;j++)
{
s[p[j]*i]=1;
if(i%p[j]==0){mul[p[j]*i]=0;break;}
else mul[p[j]*i]=-mul[i];
}
}
}
int cal(int n,int m,int k)
{
n/=k,m/=k;
int now=0,ans=0;
for(int k=1;k<=min(n,m);k=now+1)
{
now=min(n/(n/k),m/(m/k));
ans+=(sum[now]-sum[k-1])*(n/k)*(m/k);
}
return ans;
}
莫比乌斯反演 popoqqq Orz
#裴蜀定理#
若a,b是整数,且(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。 证明
#gcd & exgcd#
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
void exgcd(int a,int b,int &x,int &y)
{
if(b==0){x=1,y=0;return;}
exgcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
}
bool solve(int a,int b,int c,int &x,int &y)
{
int d=gcd(b,c);
if(c%d) return 0;//无解
a/=d,b/=d,c/=d;
exgcd(a,b,x,y);
x*=c,y*=c;
/*x+=b y-=a*/
return 1;
}
#高斯消元#
bool guass(int **a,int n)//高斯消元
{
int i=1,to;double t;//now为当前处理的行数
for(int i=1;i<=n;i++) //消去并回代Xi
{
for(to=i;to<=n;to++)
if(fabs(a[to][i])>eps) break;//找到Xi系数非0的一行
if(to>n) continue;//Xi系数全为0
if(to!=i)for(int j=1;j<=n+1;j++)
swap(a[to][j],a[i][j]);//交换
t=a[i][i];
for(int j=1;j<=n+1;j++) a[i][j]/=t;//将Xi行所有的系数变为1
for(int j=1;j<=n;j++)//j为1到n 回代与消去同时进行
{
if(j==i) continue;
t=a[j][i];//倍数
for(int k=1;k<=n+1;k++)
a[j][k]-=t*a[i][k];
}
}
for(int i=1;i<=n;i++)
if(fabs(a[i][n+1])>eps) return 0;//出现 0=常数 的情况无解
return 1;//有解
}
#费马小定理#
证明
玄学判素数
bool judge(LL x)
{
if(x==1) return 0;
if(x==2) return 1;
if(x%2==0) return 0;
for(int i=1;i<=50;i++)
{
LL p=rand()%x;
if(p==0) p++;
if(fpow(p,x-1,x)!=1) return 0;
}
return 1;
}
#组合数取模#
##1.Lucas定理##
p为质数时 C(n,m)%p = C(n/p,m/p) * C(n%p,m%p) % p 证明
注意当a < b时 C(a, b) = 0
int C(int n,int m,int p)//C(n,m) mod p p为素数
{
if(nn-m) m=n-m;
int s1=1,s2=1;
for(int i=1;i<=m;i++) s1=s1*(n-i+1)%p;
for(int i=1;i<=m;i++) s2=s2*i%p;
return s1*qpow(s2,p-2,p)%p;//逆元
}
int lucas(int n,int m,int p)//lucas定理
{
if(!n||!m) return 1;
return lucas(n/p,m/p,p)*C(n%p,m%p,p)%p;
}
##2.分解质因数##
当要求C(n ,m) % p 且p不为质数时 可以分解质因数来做。。
int n,m,ans=1;
int p[N+5],cnt[N+5],mn[N+5];
bool mk[N+5];
void get()
{
for(int i=2;i<=N;i++)
{
if(!mk[i]) p[++p[0]]=i,mn[i]=p[0];
for(int j=1;j<=p[0]&&i*p[j]<=N;j++)
{
mk[i*p[j]]=1;
mn[i*p[j]]=j;
if(i%p[j]==0)break;
}
}
}
void add(int x,int f)
{
while(x!=1)
{
cnt[mn[x]]+=f;
x/=p[mn[x]];
}
}
int qpow(int x,int k)
{
int ans=1;
while(k)
{
if(k&1) ans=ans*x%m;
k=k>>1,x=x*x%m;
}
return ans;
}
int solve()
{
int ans=1;
for(int i=1;i<=p[0];i++)
ans=ans*qpow(p[i],cnt[i])%m;
return ans;
}
例题 BZOJ 1485 [HNOI2009]有趣的数列
#卡特兰数#
C(2n,n) - C(2n,n-1) 或 C(2n,n) / (n+1)
###讲解 & 应用###
x % M1 = R1 ①
x % M2 = R2 ②
…
x % Mn = Rn
方程①等价于存在K1 满足 x = K1 * M1 + R1
方程②等价于存在K2 满足 x = K2 * M2 + R2
K1 * M1 + R1 = K2 * M2 + R2
移项得
K1 * M1 - K2 * M2 = R2 - R1
a=M1 b=M2 c=R2-R1 用exgcd解出一个x
用这个x作为特解 扩展出一个解系
X = x + k*lcm(M1, M2)
即 X % lcm(M1, M2) = x
这样两个方程就合并成了一个方程
两两合并求出方程组的解即可
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
void exgcd(int a,int b,int &x,int &y)
{
if(b==0){x=1,y=0;return;}
exgcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
}
void solve()
{
int n=read();
int a1=read(),b1=read(),a2,b2;
int a,b,c,x,y,d; bool flag=0;
for(int i=1;i
例题 POJ 2891 Strange Way to Express Integers
#BSGS#
先贴个链接 Orz
map mp;
int bsgs(int a,int b,int p)
{
if(a%p==0) return -1;
int m=(int)sqrt(p),am=qpow(a,m,p);//a^m%p
mp.clear();
b%=p;
for(int j=1,t=b;j<=m;j++)
t=t*a%p,mp[t]=j;
for(int i=1,t=1;i<=m;i++)
{
t=t*am%p;
if(mp[t]) return i*m-mp[t];
if(t==b) return i*m; //j==0
}
return -1;
}
例题 BZOJ 2242 [SDOI2011]计算器
#FFT#
FFT算法学习笔记 FFT入门 Orz
//插值的时候别忘了除n
#include
#include
#include
#include
#include
#define N 100005*4
using namespace std;
const double pi = M_PI;
typedef complex cp;
int n,m;
cp a[N],b[N];
void fft(cp *a,int n,int f)
{
if(n==1) return;
cp x[(n>>1)+1],y[(n>>1)+1];
cp w(1,0),wn(cos(2*pi/n),sin(f*2*pi/n));
for(int i=0;i<(n>>1);i++)
x[i]=a[i<<1],y[i]=a[i<<1|1];
fft(x,n>>1,f);
fft(y,n>>1,f);
for(int i=0;i<(n>>1);i++)
{
a[i]=x[i]+w*y[i];
a[i+(n>>1)]=x[i]-w*y[i];
w*=wn;
}
}
int readin()
{
cin>>n>>m;
for(int i=0;i<=n;i++)
cin>>a[i].real();
for(int i=0;i<=m;i++)
cin>>b[i].real();
m+=n;
for(n=1;n<=m;n=n<<1);
}
int main()
{
readin();
fft(a,n,1);
fft(b,n,1);
for(int i=0;i
模板 UOJ #34 多项式乘法