数论模板

翘了一上午课来机房皮。

//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=10000000+5;
int x,tot,prime[maxn],shs[maxn];
using namespace std;
int n,m;
void work(){
    for(int i=2;i<=n;i++){
        if(!shs[i]) prime[++tot]=i;
        for(int j=1;j<=tot&&prime[j]*i<=n;j++){
            shs[prime[j]*i]=1;
            if(i%prime[j]==0) break;
        }
    }
}
int main()
{
   scanf("%d%d",&n,&m);
   work();
   for(int i=1;i<=m;i++){
       scanf("%d",&x);
       if(shs[x]||x==1) printf("No\n");
       else printf("Yes\n");
   }
   return 0;
}
线性筛素数
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
ll n,p;
ll ksm(ll a,ll b){
    ll base=a,res=1;
    while(b){
        if(b&1) (res*=base)%=p;
        (base*=base)%=p;
        b>>=1;
    }
    return res;
}
int main()
{
   scanf("%d%d",&n,&p);
   for(int i=1;i<=n;i++){
   printf("%lld\n",ksm((ll)i,(ll)p-2));
   }
   return 0;
}
费马小定理求乘法逆元
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
int n,p;
void exgcd(int a,int b,int &d,int &x,int &y){
    if(b==0) {d=a,x=1,y=0;return ;}
    exgcd(b,a%b,d,y,x); y-=x*(a/b);
}
int inv(int a,int n){
    int d,x,y;
    exgcd(a,n,d,x,y);
    return d==1?(x+n)%n:-1;
}
int main()
{
   scanf("%d%d",&n,&p);
   for(int i=1;i<=n;i++){
   printf("%d\n",inv(i,p));
   }
   return 0;
}
扩展欧几里得求乘法逆元
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=1e7;
using namespace std;
long long inv[maxn];
long long n,p;
int main()
{
   scanf("%lld%lld",&n,&p);
   inv[1]=1;
   printf("%lld\n",inv[1]);
   for(int i=2;i<=n;i++)
   {inv[i]=(p-p/i)*inv[p%i]%p;
    printf("%lld\n",inv[i]);}
   return 0;
}
线性求乘法逆元
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=10000+5;
int x,tot,prime[maxn],shs[maxn];
using namespace std;
int n,m;
int query(int x){
    int mi=sqrt(x),res=x;
    for(int i=2;i<=mi;i++) if(x%i==0){
        res=res-res/i;
        while(x%i==0) x/=i;
    }
    if(x!=1) res=res-res/x;
    return res;
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++){
       scanf("%d",&x);
       printf("%d\n",query(x));
   }
   return 0;
}
单个求欧拉函数
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=32768+5;
int x,tot,prime[maxn],shs[maxn],ol[maxn];
using namespace std;
int n,m;
int work(){
    for(int i=2;i<=maxn;i++){
        if(!shs[i]) {prime[++tot]=i;ol[i]=i-1;}
        for(int j=1;j<=tot&&prime[j]*i<=maxn;j++){
            shs[prime[j]*i]=1;
            if(i%prime[j]==0){
                ol[prime[j]*i]=ol[i]*prime[j];
                break;
            }
            else ol[prime[j]*i]=ol[i]*(prime[j]-1);
        }
    }
}
int main()
{
   scanf("%d",&n);
   work();
   for(int i=1;i<=n;i++){
       scanf("%d",&x);
       printf("%d\n",ol[x]);
   }
   return 0;
}
线性筛欧拉函数
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
long long ans,n,a[65],b[65];
int main()
{
    scanf("%lld",&n);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
        for(int j=60;j>=0;j--) {
            if((1LL<<j)&a[i]) {
                if(b[j]) a[i]^=b[j];
                else {b[j]=a[i]; break;}
            }
        } 
    for(int i=60;i>=0;i--)
        if((ans^b[i])>ans) ans^=b[i];
    cout<<ans;
    return 0;
}
线性基
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=1e5+299;
typedef long long LL;
LL T,n,m,p,c[maxn];
LL ksm(LL a,LL b){
    a%=p;
    LL res=1,base=a;
    while(b){
        if(b&1) (res*=base)%=p;
        (base*=base)%=p;
        b>>=1;
    }
    return res;
}
LL C(LL n,LL m){
    if(n<m) return 0;
    return (c[n]*ksm(c[m],p-2)%p*ksm(c[n-m],p-2))%p;
}
LL lucas(LL n,LL m){
    if(!m) return 1;
    return (C(n%p,m%p)*lucas(n/p,m/p))%p;
}
int main()
{
    scanf("%lld",&T);
    while(T--){
    scanf("%lld%lld%lld",&n,&m,&p);
    c[0]=1;
    for(int i=1;i<=p;i++)
    c[i]=(c[i-1])*i%p;
    printf("%lld\n",lucas(n+m,m));
    }
   return 0;
}
卢卡斯定理
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=50000+299;
int T,a,b,c,d,k,tot,bo[maxn],prime[maxn],mu[maxn],sum[maxn]; 
void make_mu(){
    mu[1]=1; sum[1]=1;
    for(int i=2;i<=maxn;i++){
        if(!bo[i]) {prime[++tot]=i; mu[i]=-1;}
        for(int j=1;j<=tot&&prime[j]*i<=maxn;j++){
            if(i%prime[j]==0){
                bo[prime[j]*i]=1;
                mu[prime[j]*i]=0;
                break;
            }
            else {
            bo[prime[j]*i]=1;
            mu[prime[j]*i]=mu[i]*(-1);
            }
        }
        sum[i]=sum[i-1]+mu[i];
    }
}
int f(int n,int m){
    n/=k; m/=k;
    int t=min(n,m),last,ans=0;
    for(int i=1;i<=t;i=last+1){
        last=min(n/(n/i),m/(m/i));
        ans+=(sum[last]-sum[i-1])*(n/i)*(m/i);    
    }
    return ans;
}
int cul(int a,int b,int c,int d){
    int res=0; 
    res+=f(b,d);
    res-=f(a-1,d);
    res-=f(b,c-1);
    res+=f(a-1,c-1);
    return res;
}
int main()
{
   scanf("%d",&T);
   make_mu();
   while(T--){
       scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
       printf("%d\n",cul(a,b,c,d));
   }
   return 0;
}
莫比乌斯反演
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=1e6+299;
const int mod=1e9+7;
int prime[maxn*2],bo[maxn*2],tot,nxt[maxn*2],pr[20];
typedef long long LL;
LL nn,xx,n,ans;
using namespace std;
void pre(){
    for(int i=2;i<=maxn;i++){
        if(!bo[i]) { prime[++tot]=i; nxt[i]=tot; }
        for(int j=1;j<=tot&&prime[j]*i<=maxn;j++){
            bo[prime[j]*i]=1;
            nxt[prime[j]*i]=j;
            if(i%prime[j]==0) break;
        }        
    }
}
LL rongchi(LL yy){
    LL res=0;
    for(int i=1;i<(1<<pr[0]);i++){
        int flag=0,tmp=1;
        for(int j=0;j<pr[0];j++)
         if((1<<j)&i) flag++,tmp*=pr[j+1];
        if(flag&1) (res+=(LL)yy/tmp)%=mod;
        else ((res-=(LL)yy/tmp)+=mod)%=mod;
    }
    return ((LL)res+mod)%mod;
}
int main()
{
    //freopen("C.in","r",stdin);
    //freopen("C.out","w",stdout);
    scanf("%lld",&n);
    pre();
    nn=sqrt(n);
    for(int i=1;i<=nn;i++){
        pr[0]=0;
        xx=i;
        while(xx!=1){
            pr[++pr[0]]=prime[nxt[xx]];
            while(xx%pr[pr[0]]==0) 
            xx/=pr[pr[0]];
        }
        xx=i;
        ans+=((n/i-i-((rongchi(n/i)-rongchi(i))+mod)%mod)+mod)%mod;
    }
    ((ans*=2)+=1%mod)%=mod;
    printf("%lld",ans);
    return 0;
}
容斥原理 容斥简单题2.21
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
const int maxn=110;
using namespace std;
double a[maxn][maxn];
int flag,n;
inline void read(double &x){
    char ch=getchar(); double f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar())  x=x*10+ch-'0';
}
void work(){
    for(int i=1;i<=n;i++){
        int now=i;
        for(int j=i+1;j<=n;j++)
           if(fabs(a[j][i]>a[now][i])) now=j;
        if(now!=i)
           for(int j=i;j<=n+1;j++)
              swap(a[i][j],a[now][j]);
        if(a[i][i]==0) {flag=1;return;}
        for(int j=i+1;j<=n+1;j++)
           a[i][j]=a[i][j]/a[i][i];
        a[i][i]=1;
        for(int j=i+1;j<=n;j++){
           for(int k=i+1;k<=n+1;k++)
              a[j][k]-=a[i][k]*a[j][i];
              a[j][i]=0;
        }
    }
    for(int i=n;i>=1;i--)
       for(int j=i+1;j<=n;j++)
          a[i][n+1]-=a[i][j]*a[j][n+1];
}
int main()
{
   scanf("%d",&n);
   for(int i=1;i<=n;i++)
      for(int j=1;j<=n+1;j++)
          read(a[i][j]);
   work();
   if(flag) printf("No Solution\n");
   else {
   for(int i=1;i<=n;i++)
       printf("%.2lf\n",a[i][n+1]);
   }
   return 0;
}
高斯消元

 

//Achen
#include<algorithm>
#include<iostream>
#include<complex>  
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#define pi acos(-1)
const int N=3e6+7;
using namespace std;
typedef complex<double> E;
int xx,n,m,r[N],l;
E a[N],b[N]; 

template<typename T> void read(T &x) {
    T f=1; x=0; char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

void FFT(E a[],int f) {
    for(int i=0;i<n;i++) if(i<r[i]) swap(a[i],a[r[i]]);
    for(int i=1;i<n;i<<=1) {
        E wn(cos(pi/i),f*sin(pi/i));
        for(int p=i<<1,j=0;j<n;j+=p) {
            E w(1,0);
            for(int k=0;k<i;k++,w*=wn) {
                E x=a[j+k],y=w*a[j+k+i];
                a[j+k]=x+y; a[j+k+i]=x-y;
            }
        }
    }
}

int main() {
    read(n); read(m);
    for(int i=0;i<=n;i++) { read(xx); a[i]=xx;}
    for(int i=0;i<=m;i++) { read(xx); b[i]=xx;}
    m+=n;
    for(n=1;n<=m;n<<=1) l++;
    for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    FFT(a,1); FFT(b,1);
    for(int i=0;i<n;i++) a[i]=a[i]*b[i];
    FFT(a,-1);
    for(int i=0;i<=m;i++) printf("%d ",(int)(a[i].real()/n+0.5));
    return 0;
}
FFT

 

 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<cstdio>
 7 #include<vector>
 8 #include<queue>
 9 #include<cmath>
10 #include<ctime>
11 const int N=3e6+7,p=998244353,g=3,gi=332748118;
12 typedef long long LL;
13 using namespace std;
14 int n,m,l,r[N],a[N],b[N],inv;
15 
16 template<typename T> void read(T &x) {
17     T f=1; x=0; char ch=getchar();
18     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
19     if(ch=='-') f=-1,ch=getchar();
20     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
21 }
22 
23 LL ksm(LL a,LL b) {
24     LL res=1,base=a;
25     while(b) {
26         if(b&1) (res*=base)%=p;
27         (base*=base)%=p;
28         b>>=1;
29     }
30     return res; 
31 } 
32 
33 void FNT(int a[],int f) {
34     for(int i=0;i<n;i++) if(i<r[i]) swap(a[i],a[r[i]]);
35     for(int i=1;i<n;i<<=1) {
36         int wn=ksm((f==1?g:gi),(p-1)/(i<<1));
37         for(int q=(i<<1),j=0;j<n;j+=q) {
38             int w=1; 
39             for(int k=0;k<i;k++,w=(LL)w*wn%p) {
40                 int x=a[j+k],y=(LL)w*a[j+k+i]%p;
41                 a[j+k]=(LL)(x+y)%p; a[j+k+i]=(LL)(x-y+p)%p;
42             }
43         }
44     } 
45     if(f==-1) for(int i=0;i<n;i++) a[i]=(LL)a[i]*inv%p;
46 }
47 
48 int main() {
49     read(n); read(m);
50     for(int i=0;i<=n;i++) read(a[i]);
51     for(int i=0;i<=m;i++) read(b[i]);
52     m+=n;
53     for(n=1;n<=m;n<<=1) l++;
54     inv=ksm(n,p-2);
55     for(int i=0;i<n;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
56     FNT(a,1); FNT(b,1);
57     for(int i=0;i<n;i++) a[i]=(LL)a[i]*b[i]%p;
58     FNT(a,-1);
59     for(int i=0;i<=m;i++) printf("%d ",a[i]);
60     return 0;
61 }
FNT

 

 

 

数论

随便找篇码点东西

posted @ 2017-09-07 08:13  啊宸  阅读(233)  评论(0编辑  收藏  举报