矩阵树定理(bzoj2467)
//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=400+7,mod=2007;
int T,n,D[maxn][maxn];
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
int Guess(int n) {
n--;
for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) {
D[i][j]%=mod;
if(D[i][j]<0) D[i][j]+=mod;
}
int a,b,r,fl=0,ans=1;
for(int i=1;i<=n;++i) {
for(int j=i+1;j<=n;++j) {
a=D[i][i];b=D[j][i];
while(b) {
r=a/b; a=a%b; swap(a,b);
for(int k=i;k<=n;++k) D[i][k]=(D[i][k]-r*D[j][k]%mod+mod)%mod;
for(int k=i;k<=n;++k) swap(D[i][k],D[j][k]);
fl^=1;
}
}
if(!D[i][i]) return 0;
(ans*=D[i][i])%=mod;
}
if(fl) ans=(mod-ans)%mod;
return ans;
}
int main() {
read(T);
while(T--) {
read(n);
memset(D,0,sizeof(D));
for(int i=1;i<=(n<<2);++i) {
if(i%4==0) D[i][i]=4;
else D[i][i]=2;
}
for(int i=1;i<n;++i) --D[i<<2][(i+1)<<2],--D[(i+1)<<2][i<<2];
for(int i=1;i<(n<<2);++i) --D[i][i+1],--D[i+1][i];
--D[n<<2][1]; --D[1][n<<2];
--D[n<<2][4]; --D[4][n<<2];
printf("%d\n",Guess(n<<2));
}
return 0;
}
Miller-Rabin + Pollard Rho(poj1811)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int TM=25,maxn=5500;
const ll INF=1e17;
ll T,n,cnt,ans;
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
ll gcd(ll x,ll y) { return y==0? x:gcd(y,x%y); }
ll qc(ll x,ll k,ll mod) {
if(x<k) swap(x,k);
ll rs=0;
while(k) {
if(k&1) rs=(rs+x)%mod;
x=(x+x)%mod; k>>=1;
}
return rs;
}
ll qp(ll x,ll k,ll mod) {
ll rs=1;
while(k) {
if(k&1) rs=qc(rs,x,mod);
x=qc(x,x,mod); k>>=1;
}
return rs;
}
bool isprime(ll n) {
if(n==2||n==3||n==5||n==7) return 1;
if(n<2||(n%6!=1&&n%6!=5)) return 0;
ll t=0,a,m=n-1,x,y;
while((m&1)==0) t++,m>>=1;
for(int i=0;i<TM;++i) {
a=rand()%(n-2)+2;
x=qp(a,m,n);
for(int j=0;j<t;++j) {
y=qc(x,x,n);
if(y==1&&x!=1&&x!=n-1) return 0;
x=y;
}
if(y!=1) return 0;
}
return 1;
}
ll prho(ll n,ll c) {
ll i=1,k=2,d,x=rand()%(n-1)+1;
ll y=x;
while(1) {
i++;
x=(qc(x,x,n)+c)%n;
d=gcd((y-x+n)%n,n);
if(1<d&&d<n) return d;
if(y==x) return n;
if(i==k) {
y=x; k<<=1;
}
}
}
void find(ll n,ll m) {
if(isprime(n)) {
ans=min(ans,n); return;
}
ll p=n,k=m;
while(p>=n&&m) p=prho(p,m--);
find(p,k); find(n/p,k);
}
int main() {
read(T);
while(T--) {
read(n); ans=INF;
find(n,120);
if(ans==n) printf("Prime\n");
else printf("%lld\n",ans);
}
return 0;
}
/*
100
138
5
10
*/
FFT模板(洛谷)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define db double
const db PI=acos(-1);
const int maxn=2097152+10;
int n,m;
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
struct Virt{
db r,i;
Virt(db r=0.0,db i=0.0) {
this->r=r;
this->i=i;
}
Virt operator + (const Virt& x) {
return Virt(r+x.r,i+x.i);
}
Virt operator - (const Virt& x) {
return Virt(r-x.r,i-x.i);
}
Virt operator * (const Virt& x) {
return Virt(r*x.r-i*x.i,r*x.i+i*x.r);
}
}a[maxn],b[maxn];
void Rader(Virt F[],int len) {
int i,j,k;
for(i=1,j=len/2;i<len-1;++i) {
if(i<j) swap(F[i],F[j]);
k=len/2;
while(j>=k) {
j-=k;
k>>=1;
}
if(j<k) j+=k;
}
}
void FFT(Virt F[],int len,int on) {
Rader(F,len);
for(int h=2;h<=len;h<<=1) {
Virt wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
for(int j=0;j<len;j+=h) {
Virt w(1,0);
for(int k=j;k<j+h/2;++k) {
Virt u=F[k];
Virt t=w*F[k+h/2];
F[k]=u+t;
F[k+h/2]=u-t;
w=w*wn;
}
}
}
if(on==-1)
for(int i=0;i<len;++i) F[i].r/=len;
}
int main() {
read(n); read(m);
for(int i=0;i<=n;++i) read(a[i].r);
for(int i=0;i<=m;++i) read(b[i].r);
m+=n; for(n=1;n<=m+1;n<<=1);
FFT(a,n,1); FFT(b,n,1);
for(int i=0;i<n;++i) a[i]=a[i]*b[i];
FFT(a,n,-1);
for(int i=0;i<=m;++i) printf("%d ",(int)(a[i].r+0.5));
return 0;
}
拉格朗日插值法(51nod1258)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=50000+7;
const ll mod=1e9+7;
ll T,n,k;
char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!=‘-‘&&(cc<‘0‘||cc>‘9‘)) cc=getchar();
if(cc==‘-‘) ff=-1,cc=getchar();
while(cc>=‘0‘&&cc<=‘9‘) aa=aa*10+cc-‘0‘,cc=getchar();
aa*=ff;
}
void mo(ll &x){if(x>=mod) x-=mod;}
ll mi[maxn],y[maxn];
ll qp(ll x,ll k) {
ll rs=1;x%=mod;
while(k) {
if(k&1) rs=rs*x%mod;
k>>=1; x=x*x%mod;
}
return rs;
}
ll solve() {
y[0]=0;
for(int i=1;i<k+2;++i) {
y[i]=y[i-1]+qp(i,k);
mo(y[i]);
}
if(n<k+2) return y[n];
ll rs=0,t=1,nowf,tot=0;
for(int i=0;i<k+2;++i)
if(n%mod-i) t=t*(n%mod-i+mod)%mod;
else tot++;
if(tot>1) return 0;
for(int i=1;i<k+2;++i) {
if(!tot) nowf=y[i]*t%mod*qp(n-i,mod-2)%mod;
else if(n%mod-i==0) nowf=y[i]*t%mod;
else continue;
nowf=nowf*mi[i]%mod;
if(i<k+1) nowf=nowf*mi[k+1-i]%mod;
if((k+1-i)&1) nowf=nowf*(mod-1)%mod;
rs+=nowf; mo(rs);
}
return rs;
}
int main() {
read(T);
mi[1]=1;
for(int i=2;i<=50000+3;++i) mi[i]=mi[i-1]*qp(i,mod-2)%mod;
while(T--) {
read(n); read(k);
printf("%lld\n",solve());
}
return 0;
}
杜教筛留坑