数学模板整理

一些NOIP难度的

exgcd

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
ll a,b,x,y;
void exgcd(ll a,ll b,ll&x,ll&y)
{
    if(!b){x=1,y=0;return;}
    exgcd(b,a%b,y,x);
    y-=a/b*x;
}
int main()
{
    cin>>a>>b;
    exgcd(a,b,x,y);
    if(a*x+b*y==1)cout<<(x+b)%b;else cout<<(y+b)%b;
}

excrt(今年考的可能性不大因为NOI2018考过了,不过还是复习万一能骗分呢?):https://www.luogu.org/problemnew/show/P4777

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+7;
int n;
ll a[N],b[N];
ll qmul(ll a,ll b,ll mod)
{
    ll ret=0;
    while(b>0)
    {
        if(b&1)ret=(ret+a)%mod;
        a=(a+a)%mod,b>>=1;
    }
    return ret;
}
ll exgcd(ll a,ll b,ll&x,ll&y)
{
    if(!b){x=1,y=0;return a;}
    ll ret=exgcd(b,a%b,y,x);y-=a/b*x;
    return ret;
}
ll excrt()
{
    ll x,y,k,lcm=a[1],ans=b[1];
    for(int i=2;i<=n;i++)
    {
        ll A=lcm,B=a[i],c=(b[i]-ans%B+B)%B,d=exgcd(A,B,x,y);
        if(c%d)return -1;
        x=qmul(x,c/d,B/d);
        ans+=x*lcm,lcm*=B/d;
        ans=(ans%lcm+lcm)%lcm;
    }
    return(ans%lcm+lcm)%lcm;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld%lld",&a[i],&b[i]);
    printf("%lld",excrt());
}

数论分块+莫比乌斯反演https://www.lydsy.com/JudgeOnline/problem.php?id=2301

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000;
bool check[maxn+10];
int pri[maxn+10],mu[maxn+10],s[maxn+10];
void moblus()
{
    memset(check,0,sizeof(check));
    mu[1]=1;
    int tot=0;
    for(int i=2;i<=maxn;i++)
    {
        if(!check[i])
        pri[tot++]=i,mu[i]=-1;
        for(int j=0;j<tot;j++)
        {
            if(i*pri[j]>maxn)break;
            check[i*pri[j]]=1;
            if(i%pri[j]==0)
            {
                mu[i*pri[j]]=0;
                break;
            }
            else mu[i*pri[j]]=-mu[i];
        }
    }
}
long long solve(int n,int m)
{
    long long ans=0;
    if(n>m)swap(n,m);
    for(int i=1,l=0;i<=n;i=l+1)
    {
        l=min(n/(n/i),m/(m/i));
        ans+=(long long)(s[l]-s[i-1])*(n/i)*(m/i);
    }
    return ans;
}
int main()
{
    moblus();
    for(int i=1;i<=maxn;i++)
    s[i]=s[i-1]+mu[i];
    int t,a,b,c,d,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
        printf("%lld\n",solve(b/k,d/k)-solve((a-1)/k,d/k)-solve(b/k,(c-1)/k)+solve((a-1)/k,(c-1)/k));
    }
}

sg函数:https://www.luogu.org/problemnew/show/P3235

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int T,F,n,sum,sg[100010];
int getsg(int u)
{
    if(sg[u]!=-1)return sg[u];
    int r,k,now;
    bool ext[10010]={};
    for(int i=2,j;i<=u;i=j+1)
    {
        j=min(u/(u/i),u),now=0;
        r=u/i,k=u%i;
        if(i>=j)
        {
            if(k&1)now^=getsg(r+1);
            if((i-k)&1)now^=getsg(r);
            ext[now]=1;
        }
        else if(r&1)
        {
            if((i-k)&1)now^=getsg(r);
            ext[now]=1,now^=getsg(r+1),ext[now]=1;
        }
        else{
            if(k&1)now^=getsg(r+1);
            ext[now]=1,now^=getsg(r),ext[now]=1;
        }
    }
    for(int i=0;;i++)if(!ext[i])return sg[u]=i;
}
int main()
{
    memset(sg,-1,sizeof sg);
    scanf("%d%d",&T,&F);
    for(int i=0;i<F;i++)sg[i]=0;
    while(T--)
    {
        scanf("%d",&n);
        int sum=0;for(int i=1,x;i<=n;i++)scanf("%d",&x),sum^=getsg(x);
        if(!sum)printf("0 ");else printf("1 ");
    }
}

应该没了吧?

以下是NOI难度的……

线性基https://www.luogu.org/problemnew/show/P3812

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200;
int n;
ll a[N],b[N],ans;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    for (int i=1;i<=n;i++)
    {
        for(int k=52;~k;k--)
        if(a[i]&(1ll<<k))
        {
            if(!b[k]){b[k]=a[i];break;}
            else a[i]^=b[k];
        }
    }
    for(int i=52;~i;i--)
    if((ans^b[i])>ans)ans^=b[i];
    printf("%lld",ans);
}

BSGShttps://www.lydsy.com/JudgeOnline/problem.php?id=2242

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<int,int>hsh;
ll y,z,p;
ll qpow(ll a,ll b)
{
    a%=p;
    ll ret=1;
    while(b)
    {
        if(b&1)ret=ret*a%p;
        a=a*a%p,b>>=1;
    }
    return ret;
}
ll exgcd(ll a,ll b,ll&x,ll&y)
{
    if(b==0){x=1,y=0;return a;}
    ll ret=exgcd(b,a%b,y,x);y-=a/b*x;
    return ret;
}
void solve2(ll a,ll b)
{
    ll x,y,ans,d,s;
    d=exgcd(a,p,x,y);
    if(b%d){puts("Orz, I cannot find x!");return;}
    ans=b/d*x;
    s=p/d;
    ans=(ans%s+s)%s;
    printf("%lld\n",ans);
}
void solve3()
{
    y%=p,z%=p;
    if(!y)
    {
        if(!z)puts("1");else puts("Orz, I cannot find x!");
        return;
    }
    ll m=ceil(sqrt(p)),v=qpow(y,p-m-1),e=1,ret;
    hsh.clear();
    hsh[1]=m+1;
    for(ll i=1;i<=m;i++)
    {
        e=e*y%p;
        if(!hsh[e])hsh[e]=i;
    }
    ret=-1;
    for(ll i=0;i<m;i++)
    {
        if(hsh[z]){ret=i*m+(hsh[z]==m+1?0:hsh[z]);break;}
        z=z*v%p;
    }
    if(ret==-1)puts("Orz, I cannot find x!");
    else printf("%d\n",ret);
}
int main()
{
    int T,k;
    scanf("%d%d",&T,&k);
    while(T--)
    {
        scanf("%lld%lld%lld",&y,&z,&p);
        if(k==1)printf("%lld\n",qpow(y,z));
        else if(k==2)solve2(y,z);
        else solve3();
    }
}

exBSGShttps://www.luogu.org/problemnew/show/P4195

#include<bits/stdc++.h>
using namespace std;
unordered_map<int,int>h;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int exbsgs(int A,int B,int p)
{
    if(B==1)return 0;
    int cnt=0,d,k=1,q,v;
    while((d=gcd(A,p))!=1)
    {
        if(B%d)return -1;
        B/=d,p/=d,++cnt;
        k=1ll*k*(A/d)%p;
        if(k==B)return cnt;
    }
    q=ceil(sqrt(p)),v=1;
    h.clear();
    for(int i=0;i<q;i++)h[1ll*v*B%p]=i,v=1ll*v*A%p;
    k=1ll*k*v%p;
    for(int i=1;i<=q;i++)
    {
        if(h.find(k)!=h.end())return i*q-h[k]+cnt;
        k=1ll*k*v%p;
    }
    return -1;
}
int main()
{
    int a,p,b;
    while(scanf("%d%d%d",&a,&p,&b),a||p||b)
    {
        int ans=exbsgs(a,b,p);
        if(ans!=-1)printf("%d\n",ans);else puts("No Solution");
    }
}

杜教筛https://www.luogu.org/problemnew/show/P4213

#include<bits/stdc++.h>
#define R register
using namespace std;
typedef long long ll;
const int N=5e6+100;
unordered_map<int,ll>ansphi,ansmu;
int cnt,vis[N],pri[N];
ll mu[N],phi[N];
void prepare()
{
    mu[1]=phi[1]=1;
    for(int i=2;i<N;i++)
    {
        if(!vis[i])pri[++cnt]=i,mu[i]=-1,phi[i]=i-1;
        for(int j=1;j<=cnt&&i*pri[j]<N;j++)
        {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0){mu[i*pri[j]]=0,phi[i*pri[j]]=phi[i]*pri[j];break;}
            else mu[i*pri[j]]=-mu[i],phi[i*pri[j]]=phi[i]*phi[pri[j]];
        }
    }
    for(int i=1;i<N;i++)mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
ll getphi(int n)
{
    if(n<N)return phi[n];
    if(ansphi[n])return ansphi[n];
    ll ans=0;
    for(R int l=2,r;l<=n&&r<INT_MAX;l=r+1)r=n/(n/l),ans+=(r-l+1)*getphi(n/l);
    return ansphi[n]=(n+1ll)*n/2-ans;
}
ll getmu(int n)
{
    if(n<N)return mu[n];
    if(ansmu[n])return ansmu[n];
    ll ans=0;
    for(R int l=2,r;l<=n&&r<INT_MAX;l=r+1)r=n/(n/l),ans+=(r-l+1)*getmu(n/l);
    return ansmu[n]=1-ans;
}
int main()
{
    prepare();
    int T;scanf("%d",&T);
    while(T--)
    {
        int n;scanf("%d",&n);
        printf("%lld %lld\n",getphi(n),getmu(n));
    }
}

洲阁筛https://www.luogu.org/problemnew/show/SP20174

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
int cnt,cntp[N],pri[N],D3[N],low[N],vis[N],L0[N],L1[N];
ll g0[N],g1[N],f0[N],f1[N];
void prepare()
{
    D3[1]=1;
    for(int i=2;i<=1e6;i++)
    {
        if(!vis[i])pri[cnt++]=i,D3[i]=4,low[i]=i;
        for(int j=0;j<cnt&&i*pri[j]<=1e6;j++)
        {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0)
            {
                D3[i*pri[j]]=(i/low[i]==1)?(D3[i]+3):(D3[i/low[i]]*D3[low[i]*pri[j]]);
                low[i*pri[j]]=low[i]*pri[j];
                break;
            }
            D3[i*pri[j]]=D3[i]*4,low[i*pri[j]]=pri[j];
        }
    }
}
void getG(int b,int pn,ll n)
{
    for(int i=1;i<b;i++)g0[i]=i,g1[i]=n/i;
    for(int i=0;i<pn;++i)
    {
        for(int j=1;j<b&&i<L1[j];j++)
        {
            ll y=n/j/pri[i];
            g1[j]-=((y<b)?(g0[y]-max(0,min(i,cntp[y])-L0[y])):(g1[n/y]-max(0,i-L1[n/y])));
        }
        for(int j=b-1;j&&i<L0[j];j--)
        {
            ll y=j/pri[i];
            g0[j]-=g0[y]-max(0,min(i,cntp[y])-L0[y]);
        }
    }
    for(int i=1;i<b;++i)g0[i]-=cntp[i]-L0[i]+1,g1[i]-=max(0,pn-L1[i])+1;
    for(int i=1;i<b;++i)g0[i]*=4,g1[i]*=4;
}
void getF(int b,int pn,ll n)
{
    for(int i=1;i<b;i++)f0[i]=f1[i]=1;
    for(int i=pn-1;~i;i--)
    {
        for(int j=1;j<b&&i<L1[j];j++)
        {
            ll y=n/j/pri[i];
            for(int c=1;y;y/=pri[i],c++)
            if(y<b)f1[j]+=(3*c+1)*(f0[y]+4*max(0,cntp[y]-max(i+1,L0[y])));
            else f1[j]+=(3*c+1)*(f1[n/y]+4*max(0,pn-max(i+1,L1[n/y])));
        }
        for(int j=b-1;j&&i<L0[j];j--)
        {
            int y=j/pri[i];
            for(int c=1;y;y/=pri[i],c++)
            f0[j]+=(3*c+1)*(f0[y]+4*max(0,cntp[y]-max(i+1,L0[y])));
        }
    }
    for(int i=1;i<b;++i)f0[i]+=4*max(0,cntp[i]-L0[i]),f1[i]+=4*(pn-L1[i]);
}
ll getsum(ll n)
{
    int b=1,pn=0;
    while(1ll*b*b<=n)b++;
    while(1ll*pri[pn]*pri[pn]<=n)pn++;
    L0[0]=0;
    for(int i=1;i<b;i++)
    {
        L0[i]=L0[i-1];
        while(1ll*pri[L0[i]]*pri[L0[i]]<=i)L0[i]++;
    }
    L1[b]=0;
    for(int i=b-1;i;i--)
    {
        ll x=n/i;L1[i]=L1[i+1];
        while(1ll*pri[L1[i]]*pri[L1[i]]<=x)L1[i]++;
    }
    cntp[0]=0;
    for(int i=1;i<b;i++)
    {
        cntp[i]=cntp[i-1];
        while(pri[cntp[i]]<=i)cntp[i]++;
    }
    getG(b,pn,n),getF(b,pn,n);
    ll ret=f1[1];
    for(int i=1;i<b;i++)ret+=D3[i]*g1[i];
    return ret;
}
int main()
{
    prepare();
    int T;scanf("%d",&T);
    ll n;while(T--)scanf("%lld",&n),printf("%lld\n",getsum(n));
}

min25筛:loj.ac/problem/6053

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+1000,mod=1e9+7,inv2=500000004;
ll n,P,cnt,id1[N],id2[N],w[2*N],m,g[2*N],h[2*N],f[2*N],pri[N],pre[N],vis[N];
void init()
{
    for(int i=2;i<=1e5;++i)
    {
        if(!vis[i])pri[++cnt]=i,pre[cnt]=(pre[cnt-1]+i)%mod;
        for(int j=1;j<=cnt&&i*pri[j]<=1e5;++j)
        {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0)break;
        }
    }
}
int getid(ll x){return x<=P?id1[x]:id2[n/x];}
void calc()
{
    ll v,r;
    for(ll l=1;l<=n;l=r+1)
    {
        v=n/l,r=n/v;
        if(v<=P)id1[v]=++m;else id2[r]=++m;
        w[m]=v;
        ll z=v%mod;
        g[m]=(z+2)*(z-1)%mod*inv2%mod;
        h[m]=z-1;
    }
    for(ll i=1;i<=cnt;++i)
    for(ll j=1;j<=m&&pri[i]*pri[i]<=w[j];++j)
    {
        int op=getid(w[j]/pri[i]);
        g[j]=(g[j]-pri[i]*(g[op]-pre[i-1])%mod)%mod;
        h[j]=(h[j]-(h[op]-i+1))%mod;
    }
    for(int i=1;i<=m;++i)g[i]=(g[i]+mod)%mod,f[i]=(f[i]+mod)%mod,f[i]=(g[i]-h[i])%mod;
}
ll ask(ll x,ll i)
{
    if(x<=1||x<pri[i])return 0;
    ll ans=f[getid(x)]-(pre[i-1]-i+1);
    if(i==1)ans+=2;
    for(int j=i;j<=cnt&&pri[j]*pri[j]<=x;++j)
    {
        ll r=pri[j];
        for(ll e=1;r*pri[j]<=x;++e,r*=pri[j])
        ans=(ans+(pri[j]^e)*ask(x/r,j+1)+(pri[j]^(e+1)))%mod;
    }
    return ans;
}
int main()
{
    cin>>n;P=sqrt(n);
    init();
    calc();
    printf("%lld",((ask(n,1)+1)%mod+mod)%mod);
}

Miller_Rabin&Pollar_Rhohttps://www.lydsy.com/JudgeOnline/problem.php?id=3667

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll>fac;
ll mult(ll a,ll b,ll mod){return((a*b-(ll)(((long double)a*b+0.5)/mod)*mod)%mod+mod)%mod;}
ll qpow(ll a,ll b,ll mod)
{
    ll ret=1;
    while(b)
    {
        if(b&1)ret=mult(ret,a,mod);
        a=mult(a,a,mod),b>>=1;
    }
    return ret;
}
bool Miller_Rabin(ll x)
{
    if(x==2)return 1;
    int tim=10;
    while(tim--)
    {
        ll a=rand()%(x-2)+2,p,nw;
        if(qpow(a,x-1,x)!=1)return 0;
        p=x-1;
        while(!(p&1))
        {
            p>>=1,nw=qpow(a,p,x);
            if(nw!=1&&nw!=x-1&&mult(nw,nw,x)==1)return 0;
        }
    }
    return 1;
}
ll Pollard_rho(ll n,int c)
{
    ll k=2,x=rand()%(n-1)+1,y=x,d;
    for(int i=1;;++i)
    {
        x=(mult(x,x,n)+c)%n;
        d=__gcd((y-x+n)%n,n);
        if(d!=1&&d!=n)return d;
        if(x==y)return n;
        if(i==k)y=x,k<<=1;
    }
}
void Fact(ll n,int c)
{
    if(n==1)return;
    if(Miller_Rabin(n)){fac.push_back(n);return;}
    ll p=n;
    while(p>=n)p=Pollard_rho(n,c--);
    Fact(p,c);Fact(n/p,c);
}
int main()
{
    int T;cin>>T;
    while(T--)
    {
        ll n;cin>>n;
        if(n==1){puts("1");continue;}
        fac.clear(),Fact(n,233);
        sort(fac.begin(),fac.end());
        if(fac.size()==1)puts("Prime");
        else printf("%lld\n",fac[fac.size()-1]);
    }
}

高斯消元https://www.luogu.org/problemnew/show/P3389

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
int n,m,ans;
double a[110][110],x[110];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n+1;j++)
    scanf("%lf",&a[i][j]);
    //Gauss消元,求实数解
    for(int i=1;i<=n;i++)
    {
        int k=i;
        for(int j=i;j<=n;j++)
        if(fabs(a[j][i])-fabs(a[k][i])>eps)k=j;//选择当前要消的列中绝对值最大的行
        if(i!=k)
        for(int j=1;j<=n+1;j++)swap(a[i][j],a[k][j]);
        if(fabs(a[i][i])<eps){printf("No Solution\n");return 0;}
        for(int j=i+1;j<=n+1;j++)a[i][j]/=a[i][i];
        for(int j=1;j<=n;j++)
        if(i!=j)for(int k=i+1;k<=n+1;k++)
        a[j][k]-=a[j][i]*a[i][k];
    }
    for(int i=1;i<=n;i++)printf("%.2lf\n",a[i][n+1]);
}

矩阵求逆https://www.luogu.org/problemnew/show/P4783

#include<bits/stdc++.h>
using namespace std;
const int N=404,mod=1e9+7;
int n,m,a[N][N<<1];
int qpow(int a,int b)
{
    int ret=1;
    while(b)
    {
        if(b&1)ret=1ll*ret*a%mod;
        a=1ll*a*a%mod,b>>=1;
    }
    return ret;
}
int main()
{
    scanf("%d",&n);
    m=n<<1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)scanf("%d",&a[i][j]);
        a[i][n+i]=1;
    }
    for(int i=1;i<=n;++i)
    {
        for(int j=i;j<=n;++j)
        if(a[j][i])
        {
            for(int k=1;k<=m;++k)swap(a[i][k],a[j][k]);
            break;
        }
        if(!a[i][i]){puts("No Solution");return 0;}
        int r=qpow(a[i][i],mod-2);
        for(int j=i;j<=m;++j)a[i][j]=1ll*a[i][j]*r%mod;
        for(int j=1;j<=n;++j)
        if(j!=i)
        {
            r=a[j][i];
            for(int k=i;k<=m;++k)a[j][k]=(a[j][k]-1ll*r*a[i][k]%mod+mod)%mod;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=n+1;j<=m;j++)printf("%d ",a[i][j]);
        puts("");
    }
}

exLucashttps://www.luogu.org/problemnew/show/P4720

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+7;
ll n,m,p,fac[N],PI[N],PK[N],cnt;
ll qpow(ll a,ll b,ll p)
{
    ll ret=1;
    while(b)
    {
        if(b&1)ret=ret*a%p;
        a=a*a%p;b>>=1;
    }
    return ret;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b){x=1;y=0;return;}
    exgcd(b,a%b,y,x);y-=a/b*x;
}
ll inv(ll n,ll p)
{
    ll a=n,b=p,x,y;
    exgcd(a,b,x,y);
    x=(x%b+b)%b;
    if(!x)x+=b;
    return x;
}
ll mul(ll n,ll pi,ll pk)
{
    if(!n)return 1;
    ll ans=1;
    if(n/pk)ans=ans*fac[pk]%pk,ans=qpow(ans,n/pk,pk)%pk;
    ans=ans*fac[n%pk]%pk;
    return ans*mul(n/pi,pi,pk)%pk;
}
ll C(ll n,ll m,ll p,ll pi,ll pk)
{
    if(n<m)return 0;
    int k=0;ll ans=1;
    fac[0]=fac[1]=1;
    for(int i=2;i<=pk;i++)
    if(i%pi)fac[i]=fac[i-1]*i%pk;
    else fac[i]=fac[i-1];
    ll a=mul(n,pi,pk),b=mul(m,pi,pk),c=mul(n-m,pi,pk);
    for(ll i=n;i;i/=pi)k+=i/pi;
    for(ll i=m;i;i/=pi)k-=i/pi;
    for(ll i=n-m;i;i/=pi)k-=i/pi;
    ans=a*inv(b,pk)%pk*inv(c,pk)%pk*qpow(pi,k,pk)%pk;
    return ans*(p/pk)%p*inv(p/pk,pk)%p;
}
ll CRT(ll n,ll m,ll p)
{
    if(n<m)return 0;
    ll ans=0;
    for(int i=1;i<=cnt;i++)ans=(ans+C(n,m,p,PI[i],PK[i]))%p;
    return ans;
}
void prepare(int p)
{
    cnt=0;
    for(int i=2;i*i<=p;++i)
    if(p%i==0)
    {
        PI[++cnt]=i;PK[cnt]=1;
        while(p%i==0)p/=i,PK[cnt]*=i;
    }
    if(p!=1)PI[++cnt]=PK[cnt]=p;
}
int main()
{
    cin>>n>>m>>p;
    prepare(p);
    cout<<CRT(n,m,p);
}

 

未完待续……

posted @ 2019-06-05 18:16  hfctf0210  阅读(288)  评论(0编辑  收藏  举报