• 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;
    }

     

     

     

    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    uva 10491 Cows and Cars
    uva 10910 Marks Distribution
    uva 11029 Leading and Trailing
    手算整数的平方根
    uva 10375 Choose and divide
    uva 10056 What is the Probability?
    uva 11027 Palindromic Permutation
    uva 10023 Square root
    Ural(Timus) 1081. Binary Lexicographic Sequence
    扩展欧几里得(求解线性方程)
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7582955.html
Copyright © 2020-2023  润新知