• hdu 6169 Senior PanⅡ Miller_Rabin素数测试+容斥


    Senior PanⅡ

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)



    Problem Description

    Senior Pan had just failed in his math exam, and he can only prepare to make up for it. So he began a daily task with Master Dong, Dong will give a simple math problem to poor Pan everyday.
    But it is still sometimes too hard for Senior Pan, so he has to ask you for help.
    Dong will give Pan three integers L,R,K every time, consider all the positive integers in the interval [L,R], you’re required to calculate the sum of such integers in the interval that their smallest divisor (other than 1) is K.

     
    Input
    The first line contains one integer T, represents the number of Test Cases.
    Then T lines, each contains three integers L,R,K(1≤L≤R≤10^11,2≤K≤10^11)
     
    Output
    For every Test Case, output one integer: the answer mod 10^9+7
     
    Sample Input
    2 1 20 5 2 6 3
     
    Sample Output
    Case #1: 5 Case #2: 3
     
    Source

    占坑;。。。其实是不想写,容斥我用莫比乌斯函数推出来的

    突然发现我sb,为什么写大素数测试啊。。。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<bitset>
    #include<set>
    #include<map>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define eps 1e-8
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=3e3+10,M=1e6+10,inf=1e9+10;
    const LL INF=1e18+10,mod=1e9+7;
    
    
    LL gcd(LL a, LL b)
    {
        return b? gcd(b, a % b) : a;
    }
    
    LL multi(LL a, LL b, LL m)
    {
        LL ans = 0;
        a %= m;
        while(b)
        {
            if(b & 1)
            {
                ans = (ans + a) % m;
                b--;
            }
            b >>= 1;
            a = (a + a) % m;
        }
        return ans;
    }
    
    LL quick_mod(LL a, LL b, LL m)
    {
        LL ans = 1;
        a %= m;
        while(b)
        {
            if(b & 1)
            {
                ans = multi(ans, a, m);
                b--;
            }
            b >>= 1;
            a = multi(a, a, m);
        }
        return ans;
    }
    const int Times = 10;
    bool Miller_Rabin(LL n)
    {
        if(n == 2) return true;
        if(n < 2 || !(n & 1)) return false;
        LL m = n - 1;
        int k = 0;
        while((m & 1) == 0)
        {
            k++;
            m >>= 1;
        }
        for(int i=0; i<Times; i++)
        {
            LL a = rand() % (n - 1) + 1;
            LL x = quick_mod(a, m, n);
            LL y = 0;
            for(int j=0; j<k; j++)
            {
                y = multi(x, x, n);
                if(y == 1 && x != 1 && x != n - 1) return false;
                x = y;
            }
            if(y != 1) return false;
        }
        return true;
    }
    
    int vis[M];
    vector<int>pri;
    void init()
    {
        for(int i=2;i<=350000;i++)
        {
            if(!vis[i])
            pri.push_back(i);
            for(int j=i+i;j<=350000;j+=i)
                vis[j]=1;
        }
    }
    LL out;
    void dfs(LL p,int pos,int step,LL L,LL R,LL K)
    {
        if(p*K>R)return;
        LL d=p*K;
        LL x1=(R/d),x2=(L-1)/d;
        //cout<<p<<" "<<d<<" "<<step<<endl;
        //cout<<p<<" "<<pos<<" "<<step<<endl;
        if(step%2==0)
        {
            out+=((multi(x1,x1+1,mod)*1LL*500000004)%mod)*d;
            out%=mod;
            out-=((multi(x2,x2+1,mod)*1LL*500000004)%mod)*d;
            out=(out%mod+mod)%mod;
        }
        else
        {
            out-=((multi(x1,x1+1,mod)*1LL*500000004)%mod)*d;
            out=(out%mod+mod)%mod;
            out+=((multi(x2,x2+1,mod)*1LL*500000004)%mod)*d;
            out%=mod;
        }
        for(int i=pos;i<pri.size();i++)
        {
            if(pri[i]>=K)return;
            if(p*pri[i]*K>R)return;
            dfs(p*pri[i],i+1,step+1,L,R,K);
        }
    }
    int main()
    {
        init();
        int T,cas=1;
        scanf("%d",&T);
        while(T--)
        {
            out=0;
            LL l,r,k;
            scanf("%lld%lld%lld",&l,&r,&k);
            bool isp=Miller_Rabin(k);
            printf("Case #%d: ",cas++);
            if(!isp){
                printf("0
    ");
                continue;
            }
            if(k>=350000)
            {
                if(l<=k&&r>=k)printf("%lld
    ",k%mod);
                else printf("%lld
    ",0);
            }
            else
            {
                dfs(1,0,0,l,r,k);
                printf("%lld
    ",out);
            }
        }
        return 0;
    }
  • 相关阅读:
    一个支持asp.net2.0和Sql server及Access的免费空间
    ASP.NET2.0数据指南中文版索引
    所阅读的ASP.NET 2.0文章
    SQL SERVER实用技巧
    2000/XP/2003常见问题集锦
    解讀多重啟動引導文件——BOOT.INI
    【译】Html5游戏开发示例(2)
    unity3d 鼠标事件穿透GUI的处理
    【译】Html5游戏开发示例(3)
    unity3d 截屏
  • 原文地址:https://www.cnblogs.com/jhz033/p/7412586.html
Copyright © 2020-2023  润新知