zoukankan      html  css  js  c++  java
  • 9.23 NOIP模拟题(数学专练)

                                                            数论基础 专题测试 


                                                                                                                                                                命题人:清华大学 王赢绪

    /*
    水题
    答案为C(n-k,m-1)  预处理阶乘和逆元,O(1)算答案 
    开始读错题了!!!朱一乐!!! 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 1000003
    #define mod 1000000007
    #define ll long long
    
    using namespace std;
    ll fac[N]={1,1},inv[N]={1,1},f[N]={1,1};
    ll n,m,k,ans,cnt;
    
    inline ll read()
    {
        ll x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    inline int C(ll a,ll b)
    {
        if(a<b) return 0;
        return fac[a]*inv[b]%mod*inv[a-b]%mod;
    }
    
    inline void init()
    {
        for(int i=2;i<N;i++)
        {
            fac[i]=fac[i-1]*i%mod;
            f[i]=(mod-mod/i)*f[mod%i]%mod;
            inv[i]=inv[i-1]*f[i]%mod; 
        }
    }
    
    int main()
    {
        freopen("ball.in","r",stdin);
        freopen("ball.out","w",stdout);
        n=read();m=read();k=read();
        init();
        ans=C(n-k,m-1);    
        printf("%I64d
    ",ans%mod);
        fclose(stdin);fclose(stdout);
        return 0;
    }

     

     

     

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 10000001
    #define ll long long
    
    using namespace std;
    ll n,t,m,ans,cnt,tot;
    ll phi[N+10],prime[N+10];
    bool mark[N+10];
    
    void getphi()
    {
        phi[1]=1;mark[1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!mark[i]) prime[++tot]=i,phi[i]=i-1;
            for(int j=1;j<=tot;j++)
            {
                if(i*prime[j]>n) break;
                mark[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    phi[i*prime[j]]=phi[i]*prime[j];break;
                }
                else phi[i*prime[j]]=phi[i]*(prime[j]-1);
            }
        }
    }
    
    ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
    
    int main()
    {
        freopen("gcd.in","r",stdin);
        freopen("gcd.out","w",stdout);
        scanf("%d",&t);scanf("%d",&n);
        if(t==1)
        {
            getphi();
            ans=0;
            for(int i=2;i<=n;i++)
            ans+=phi[i];
            printf("%d
    ",ans*2+1);
        }
        else if(n<10000)
        {
            getphi();
            ans=0;
            for(int i=1;i<=n;i++)
              for(int j=1;j<=n;j++)
                {
                    int no=gcd(i,j);
                    if(!mark[no]) ans++;
                }
            printf("%d
    ",ans);
        }
        if(t==2 && n==10000)
        {
            printf("27497027
    ");
            return 0;
        }
        return 0;
    }
    80暴力

     

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long int64;
    const int MAXN=10000005;
    
    int T,n;
    int top,prm[MAXN];
    int64 phi[MAXN];
    bool vis[MAXN];
    int64 ans;
    
    int main()
    {
        freopen ("gcd.in","r",stdin);
        freopen ("gcd.out","w",stdout);
        cin>>T>>n;
        phi[1]=1;
        for (int i=2;i<=n;i++)
        {
            if (!vis[i]) prm[++top]=i,phi[i]=i-1;
            for (int j=1;j<=top&&i*prm[j]<=n;j++)
            {
                vis[i*prm[j]]=true;
                if (i%prm[j]==0)
                {
                    phi[i*prm[j]]=phi[i]*prm[j];
                    break;
                }
                else phi[i*prm[j]]=phi[i]*(prm[j]-1);
            }
        }
        if (T==1)
        {
            for (int i=1;i<=n;i++) ans+=phi[i];
            ans=2*ans-1;
        }
        if (T==2)
        {
            for (int i=2;i<=n;i++) phi[i]+=phi[i-1];
            for (int i=1;i<=top;i++) ans+=phi[n/prm[i]]*2-1;    
        }
        cout<<ans<<endl;
        return 0;
    }

     

     

     

    题解:

     

    /*
    这题好到没话说 
    */
    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long int64;
    const int MAXN=10000005;
    
    int prm[MAXN/10];
    bool vis[MAXN];
    int64 phi[MAXN];
    int ti[MAXN],ys[MAXN];
    int MOD;
    
    int64 pw(int64 x,int64 y)
    {
        int64 res=1;
        for (;y;y>>=1)
        {
            if (y&1) res=(res*x)%MOD;
            x=(x*x)%MOD;
        }
        return res;
    }
    
    void exgcd(int64 a,int64 b,int64 &xx,int64 &yy)
    {
        if (!b)
        {
            xx=1;
            yy=0;
            return;
        }
        int64 x1,x2;
        exgcd(b,a%b,x1,x2);
        xx=x2;
        yy=x1-(a/b)*x2;
    }
    
    void pre_prime_3()
    {
        int top=0;
        phi[1]=1;
        for (int i=2;i<=10000000;i++)
        {
            if (!vis[i]) prm[++top]=i,phi[i]=i-1;
            for (int j=1;j<=top&&i*prm[j]<=10000000;j++)
            {
                vis[i*prm[j]]=true;
                if (i%prm[j]==0)
                {
                    phi[i*prm[j]]=phi[i]*prm[j];
                    break;
                }
                phi[i*prm[j]]=phi[i]*(prm[j]-1);
            }
        }
    }
    
    void pre_prime_4()
    {
        int top=0;
        ys[1]=1;
        for (int i=2;i<=10000000;i++)
        {
            if (!vis[i]) prm[++top]=i,ys[i]=2,ti[i]=1;
            for (int j=1;j<=top&&i*prm[j]<=10000000;j++)
            {
                vis[i*prm[j]]=true;
                if (i%prm[j]==0)
                {
                    ys[i*prm[j]]=ys[i]/(ti[i]+1)*(ti[i]+2);
                    ti[i*prm[j]]=ti[i]+1;
                    break;
                }
                ys[i*prm[j]]=ys[i]*ys[prm[j]];
                ti[i*prm[j]]=1;
            }
        }
    }
    
    void work1()
    {
        int T,a,b;
        int64 x,y;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d%d",&a,&b);
            exgcd(a,b,x,y);
            x=(x%b+b)%b;
            printf("%d
    ",(int)x);
        }
    }
    
    void work2()
    {
        int T;
        scanf("%d",&T);
        while (T--)
        {
            int a,ans=2000000000;
            scanf("%d%d",&a,&MOD);
            int p=(int)sqrt(MOD-1);
            for (int i=1;i<=p;i++)
            {
                if ((MOD-1)%i!=0) continue;
                if (pw(a,i)==1) ans=min(ans,i);
                if (pw(a,(MOD-1)/i)==1) ans=min(ans,(MOD-1)/i);
            }
            printf("%d
    ",ans);
        }
    }
    
    void work3()
    {
        pre_prime_3();
        for (int i=1;i<=10000000;i++) phi[i]+=phi[i-1];
        int T,n,m;
        int64 ans;
        scanf("%d",&T);
        while (T--)
        {
            ans=0;
            scanf("%d%d",&n,&m);
            if (n>m) swap(n,m);
            int last;
            for (int i=1;i<=n;i=last+1)
            {
                int nn=n/i,mm=m/i;
                nn=n/nn,mm=m/mm;
                last=min(nn,mm);
                ans+=(phi[last]-phi[i-1])*(n/i)*(m/i);
            }
            printf("%lld
    ",ans);
        }
    }
    
    void work4()
    {
        pre_prime_4();
        for (int i=1;i<=10000000;i++) ys[i]+=ys[i-1];
        int T,n;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);
            printf("%d
    ",ys[n]);
        }
    }
    
    int main()
    {
        freopen ("years.in","r",stdin);
        freopen ("years.out","w",stdout);
        int sub_task;
        scanf("%d",&sub_task);
        if (sub_task==1) work1();
        if (sub_task==2) work2();
        if (sub_task==3) work3();
        if (sub_task==4) work4();
        return 0;
    }

     

     

     

    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    【SDOI2019】—世界地图(虚树+Kruscal)
    【SDOI2019】—世界地图(虚树+Kruscal)
    【SDOI2019】—热闹的聚会与尴尬的聚会(图论)
    【SDOI2019】—热闹的聚会与尴尬的聚会(图论)
    【BZOJ3153】—Sone1(Top-Tree)
    【BZOJ3153】—Sone1(Top-Tree)
    【UOJ #284】— 快乐游戏鸡(长链剖分+线段树)
    【UOJ #284】— 快乐游戏鸡(长链剖分+线段树)
    【BZOJ4372】—烁烁的游戏(动态点分治)
    【BZOJ4372】—烁烁的游戏(动态点分治)
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7582955.html
Copyright © 2011-2022 走看看